Jason Torres

Jason Torres

Community Manager, Developer Advocate, Filmmaker

The Architecture of a Year: Why I Built FullCircle

Time is our only non-renewable resource. I realized that.....

Freshman Year: My 2025 Debut in Tech

People say a long career in film prepares you for a lot...

Building Holiday Magic with AI: The 2025 Santa Tracker

Resurrecting a family tradition with an 8-bit Santa Tracker powered by real-time AI voice orchestration.

The Tech Conference That Wasn't Selling Anything

Reflections on community over commerce and why the best events feel less like sales pitches.

How I built this portfolio

A look under the hood of this site using Laravel, Tailwind, and a minimal design philosophy.

LinkedIn: Musings of an Idiot

The Exact Prompt to Generate Lofi Chill Tracks With Claude and Zero Dependencies

Copy this. Paste it. Get music. I'll explain the weird parts. People asked how the audio side of the stream works, specifically whether they could replicate it. Yes. Here's exactly how. The whole thing runs on FFmpeg. No pip install. No audio libraries. No samples to license. Claude writes Python that shells out to FFmpeg for every synthesis step, and FFmpeg does the actual math. Your machine needs two things: Python 3 and FFmpeg. That's it. Here's the prompt. Below it I'll explain why specific parts are phrased the way they are, because if you leave any of them out Claude will make choices that break everything quietly. I've also got a section at the end on the changes I made to lock in the lofi chill sound and make sure the stems actually sound different from each other. The Prompt I want to generate lofi chill hip hop music using only FFmpeg — no pip packages, no numpy, no audio libraries of any kind. Everything should be synthesized using FFmpeg's lavfi source filters and exported as WAV stems, then mixed into MP3 tracks. The target aesthetic is lofi chill: warm, slightly muffled, with a sense of space and slowness. Think late-night study music. Frequencies should skew dark (cut highs, keep lows and low-mids). Echo and reverb should feel generous. Melody should be sparse enough that the silence is part of the composition. Write two Python scripts: --- SCRIPT 1: generate_stems.py Generate stems in these four categories inside a tools/stems/ directory: tools/stems/drums/ — 8 drum loop WAVs tools/stems/chords/ — 8 chord progression WAVs tools/stems/bass/ — 6 bass line WAVs tools/stems/melody/ — 6 melody phrase WAVs All stems should be 85 BPM, 8 bars long (~22.6 seconds), 44100 Hz. Each stem variant must have a distinct character — not just different notes or different swing amounts, but different tonal texture and feel. Vary the lowpass cutoff frequencies, echo tail lengths, reverb amounts, attack and decay rates, and note density across variants. A listener should be able to tell drums_01 and drums_04 apart after 5 seconds, not after 3 minutes. DRUMS: Use FFmpeg's aevalsrc filter to synthesize kick, snare, and hihat from math expressions evaluated per sample. A kick is a sine wave whose frequency and amplitude both decay exponentially from the start of each beat period. A snare is white noise from anoisesrc with a rhythmic amplitude envelope via aeval. Hihat is the same but filtered to high frequencies with a faster decay. For the lofi chill aesthetic, drums should feel muffled and slightly roomy: - Apply a lowpass between 7000-10000 Hz on the full drum mix (vary per variant — some darker, some slightly brighter but never crispy) - Add a short aecho to the snare (delay 30-60ms, decay 0.2-0.35) to give it a small-room feel rather than a dry studio snap - Hihat amplitude should be noticeably quieter than kick and snare — present but not forward Build 8 variants with different swing amounts (0% to 55% swing), different kick and snare decay rates, and different room character from the echo settings. Mix layers with amix. CRITICAL: FFmpeg's lavfi format uses commas as filter chain separators. This means mod(t, period) will break — the comma splits the expression mid-parse and the evaluator throws a confusing error. Replace every mod(a, b) with the equivalent a - floor(a/b)*b, which produces identical results with no commas. Write a helper function called fmod(a, b) that returns this expression as a string, and use it everywhere. CHORDS: Generate 8 different minor 7th chord progressions across different keys (Dm7, Cm7, Am7, Fm7, Em7, and others). Each progression has 4 chords, each lasting 2 bars. Use FFmpeg's sine lavfi source for each note in a chord, mix the notes with amix. For the lofi chill aesthetic, chords should feel warm and washy: - Apply aecho with generous settings: in_gain 0.5-0.7, out_gain 0.4-0.6, delays 60-120ms, decays 0.25-0.45. Vary these per variant so some progressions feel more intimate and some feel more spacious. - Apply lowpass between 3500-4500 Hz per variant (vary this — some chord sets should feel darker and more muffled, others slightly more open) - Add a short attack fade (80-120ms) to each chord to soften the onset - Include a very subtle highpass at 80 Hz to keep the low end clean Export each progression as a full 8-bar WAV. BASS: Generate 6 bass lines that follow the root notes of corresponding chord progressions. Each bass note is two sine waves: the fundamental frequency and its second harmonic mixed at 70%/15%. Apply a hard lowpass at 250-300 Hz (vary per variant). Fire notes on beats 1 and 3 for most variants, but allow 1-2 variants to use a slightly busier pattern (beat 1, the "and" of 2, and beat 3) for rhythmic variety. Hold notes for 35-50% of bar length (vary this — shorter notes feel more staccato and groove harder, longer notes feel more sustained and meditative). Apply a small aecho (delay 40-70ms, decay 0.15-0.25) to add warmth. MELODY: Generate 6 sparse pentatonic melody phrases using random note placement. Use pentatonic scales in different keys matched to the chord progressions. For the lofi chill aesthetic, melody should lean into space: - For each bar, there should be a 60-70% chance of silence (vary per variant — some should be very sparse, one or two notes per loop, others slightly busier but never dense) - When notes are placed, use 1-2 notes at random 8th-note positions, each held for 25-50% of a bar - Apply generous aecho (delay 50-90ms, decay 0.25-0.40) - Apply lowpass between 3500-4200 Hz - Apply a very gentle volume fade-out to each note (not just at the stem end, but on each individual note) so notes dissolve rather than cut Use a fixed random seed per variant so results are reproducible. Also generate a vinyl crackle/room noise layer and save it as tools/stems/texture/texture_01.wav: use anoisesrc with pink noise at -32 dB mixed with a very subtle anoisesrc white noise at -38 dB. Apply lowpass at 6000 Hz. This adds the faint ambient texture that makes synthesized lofi tracks feel less sterile. The mixer should include this as an optional fifth layer at -20 dB under everything. --- SCRIPT 2: mix_stems.py Randomly combine one stem from each category into 3-minute MP3 tracks. Accept a --tracks argument for how many to generate. Track progress in a .mix_progress.json file so the script is resumable if interrupted. For each track: - Use -stream_loop -1 on all stems so they loop to fill 3 minutes - Mix with amix and apply per-category volume levels: drums: -1 dB chords: -3 dB bass: -6 dB melody: -8 dB texture: -20 dB (if texture file exists) - Apply loudnorm=I=-14:TP=-1:LRA=11 for consistent perceived loudness - Fade in 2 seconds, fade out 3 seconds (longer fades suit the chill vibe) - Export as 192k MP3 with ID3 tags: title: a generated name combining a mood word and track number artist: whatever name you want on the tracks album: a collection name Print progress as each track completes with the stem filenames used, elapsed time, and ETA for the full batch. --- Additional requirements for both scripts: - Python 3.9 compatible. Use Optional[Path] from typing instead of Path | None. - Use subprocess with capture_output=True and check returncode. Print the last 400 characters of stderr on failure so errors are debuggable. - No numpy. No scipy. No external packages at all. Only stdlib + subprocess. - The stems directory structure should be created automatically if missing. - Include a temporary working directory (tools/_tmp/) for intermediate files and clean it up after stem generation completes. Why These Constraints Are Phrased So Specifically "No pip packages, no numpy." Without this Claude will reach for numpy immediately. It's the natural tool for sample-level audio work. But numpy may not be installed on your machine, and installing it just to generate stems you only need once is annoying. FFmpeg handles all the signal math internally and is almost certainly already on your system. The fmod section. This is the one that will burn you if you skip it. Claude knows mod() is how you calculate position within a repeating period. It will use mod(t, KICK_P) in the aevalsrc expression and it will not warn you that this breaks FFmpeg's filter graph parser. The error you get is Missing ')' or too many args in 'mod(t' which is technically correct but requires you to already know about the comma-separator issue to understand it. Including the explanation in the prompt means Claude writes the right thing the first time. "Python 3.9 compatible." If you're on a Mac with a system Python, there's a good chance it's 3.9. Python 3.10 introduced the Type | None union syntax. Claude defaults to that syntax and your script will throw a TypeError: unsupported operand type(s) for | on the first run if your Python is older. Specifying 3.9 compatibility makes Claude use Optional[Path] from the typing module instead, which works everywhere. "Print the last 400 characters of stderr on failure." FFmpeg errors are long and the relevant part is almost always at the end. Without this Claude will either swallow errors silently or print the full multi-kilobyte stderr that scrolls your terminal into oblivion. 400 characters is just right. The volume levels. These aren't arbitrary. Drums louder than everything else means the rhythm drives the feel. Melody at -8 dB means it floats rather than competes. Texture at -20 dB means you feel it more than you hear it, which is exactly right for vinyl crackle. If you let Claude pick these freely you get a mix where everything is at the same volume and it sounds like a test file. "Fixed random seed per variant." Without this the melody variants are different every time you run stem generation, which means you can't reproduce a combination that sounded good. Fixed seeds mean a given melody variant always has the same note pattern. What Changed for Lofi Chill and Variance The original version of the prompt generated music that worked but was kind of generic. All the drum variants sounded close enough that you couldn't tell which was playing without checking. Chords were all at the same brightness. Melody was consistent across variants in ways that made the whole library feel like one long track with minor variations. Two additions fixed both problems. The aesthetic brief up front. "Warm, slightly muffled, sense of space and slowness. Think late-night study music." This is not fluff. Claude uses this to make dozens of small decisions — how aggressive to make the lowpass, how long to make echo tails, how much silence to put in the melody. Without an aesthetic target it optimizes for technically correct and lands on something that sounds like stock audio. With it, the decisions compound in the right direction. Explicit variance instructions per category. Telling Claude to vary the lowpass cutoff, echo tail lengths, and note density per variant rather than just the swing amount or the notes means each stem has a different tonal fingerprint. Drums variants now range from genuinely muffled to merely dark. Chord variants range from intimate and close to spacious and washy. Melody variants range from one or two notes the entire loop to slightly busier. When you combine them randomly you get mixes that actually feel distinct rather than mixes that are technically different but perceptually identical. The vinyl crackle texture layer is optional but worth including. At -20 dB it's inaudible as a distinct element. What it does is fill the silence between notes with just enough noise that the track doesn't feel like it was made by software. It's the difference between "this sounds like lofi" and "this sounds like lofi from a vinyl rip." Which one you want is up to you, but you should know the option is there. What You Get After running python3 tools/generate_stems.py you have 28 stem WAVs plus a texture file. It takes about 30 seconds. After running python3 tools/mix_stems.py --tracks 60 you have 60 MP3s. It takes about 2.5 minutes. The math: 8 × 8 × 6 × 6 = 2,304 unique stem combinations. Every track is a random draw from that pool. None of them are identical. None of them sound like they came from the same sample. And because the stems themselves now have distinct tonal characters rather than just distinct notes, tracks that happen to share a drum variant still sound different if the chord or melody variant is different enough. The tracks are 3 minutes each with loudness normalization, longer fades than the original version, and that low-level texture layer underneath everything. Put one on. It should feel like something you'd leave running for hours without noticing it's generative. The One Thing Claude Still Might Get Wrong Even with a thorough prompt, Claude occasionally generates the filter_complex string incorrectly when building the mixer. Specifically, when it constructs the amix graph for four or five inputs, it sometimes gets the labeled output routing wrong and FFmpeg throws a "No such filter 'out'" error. If that happens, paste the error back into Claude with this addition: The filter_complex string is malformed. Make sure each input is labeled, routed through its volume filter to a named output, and that the amix inputs argument matches the exact number of labeled streams being mixed. The final output must be explicitly mapped with -map [out]. That fixes it every time. Variations Worth Trying You can nudge the BPM down to 78-82 for a slower, more meditative feel. 85 is solidly lofi hip hop. Low 80s starts to feel more ambient. Below 75 it gets sleepy in a way that might be exactly what you want or might be too much depending on the context. You can push the lowpass cutoffs lower across the board — say 3000 Hz max instead of 4500 — for a murkier, more underwater quality. Some people love this. Some people find it fatiguing. Try it on a few tracks before committing. You can add more stem variants by incrementing the counts in the prompt. Going from 8 to 12 drum patterns increases unique combinations from 2,304 to 5,184. Going from 6 to 10 melody phrases gets you to 9,600. Generation time scales linearly and is never a bottleneck. The loudness target of -14 LUFS is standard for YouTube and most streaming platforms. Apple Music targets -16 LUFS. If you're specifically targeting Apple, change the loudnorm I value to -16. The filter handles it without any other changes. let me know if this works for ya!! -JSON

Jul 23, 2026

Newsletter

My first 90 days in as Developer Advocate at JetBrains. Here's what actually happened.

I started on March 16 not entirely sure what the first week would look like. My background was in Community Management. I knew how to listen at scale, build trust, and translate developer sentiment into something actionable. The question was whether that would translate into a DA role at JetBrains Short answer: yes. But the real answer is more interesting. 𝗪𝗵𝗮𝘁 𝗜 𝘀𝗵𝗶𝗽𝗽𝗲𝗱 In week two, I flew to Amsterdam. I streamed the WebStorm 2026.1 release live on YouTube (51 minutes, 10K+ views). I sat down with Jan-Niklas Wortmann and Vitaly Bragilevsky for an interview that's still forthcoming. And I attended KubeCon. All of that in week two! That set the tone for everything that followed. In 90 days total, I produced 7 pieces of video content for WebStorm across Twitter/X, LinkedIn, and YouTube, generating 100k+ combined views. Across all platforms, release content averaged 14K+ views, while non-release content averaged around 9K. That gap used to be a lot wider. Closing it is the whole game. https://www.youtube.com/watch?v=eyWKDA09ETA&t=1663s More importantly, I stopped treating content as product announcements and started treating it as arguments. Arguments for why the IDE still matters. Why semantic understanding beats text search when your agent is hallucinating TypeScript types. Why your refactoring workflow shouldn't require a cut-and-paste ritual. Developers respond to that. The metrics show it, but the comments and DMs show it more, and for me thats the biggest piece. 𝗪𝗵𝗮𝘁 𝗜 𝗯𝘂𝗶𝗹𝘁 𝗶𝗻𝘁𝗲𝗿𝗻𝗮𝗹𝗹𝘆 The content didn't happen in isolation. I embedded in the WebStorm product team's weekly syncs, the JS/TS Eco lean coffee sessions, and regular 1:1s with my team leads. I opened YouTrack issues, worked through the copyediting pipeline (shoutout to #copyedit), and started pulling in community signal from Reddit, Discord, and the WebStorm mentions channel to inform what I made. I also pushed forward on the tooling side. CapCut Team license (sorry Jan-Niklas), Screen Studio, proper content production infrastructure. You can't produce at volume on vibes. 𝗢𝗻 𝗽𝗮𝗿𝘁𝗻𝗲𝗿𝘀𝗵𝗶𝗽𝘀 𝗮𝗻𝗱 𝗰𝗼𝗺𝗺𝘂𝗻𝗶𝘁𝘆 The collaboration meetings were one of the more exciting things I got pulled into. The TC39 meeting coverage at the Amsterdam office was a highlight. That's the kind of intersection of community and product I came here for. I also started doing something I think is underrated in DevRel: introductions. Connecting developers I know and trust with the right people at JetBrains. It's slow trust-building, but it compounds. 𝗪𝗵𝗮𝘁'𝘀 𝘀𝘁𝗶𝗹𝗹 𝗼𝗽𝗲𝗻 JetBrains Remoting/Gateway is my first major product focus. The developer sentiment around it is complicated. There's a real trust gap between what the product can do and what the community believes about it. That gap is a DA problem, and I intend to close it. I also want to formalize the Champions program more concretely, and tighten the content cadence. Seven pieces in 90 days is a start. I want weekly. 𝗧𝗵𝗲 𝗯𝗶𝗴𝗴𝗲𝗿 𝘁𝗵𝗶𝗻𝗴 "community IS the job" I came into this role from community, and I think some people raised an eyebrow. Myself included. But I think community IS the job. You just stop moderating and start building. Building presence, building arguments, building trust in rooms and on platforms where developers are already having the conversations that matter. Day 91 starts Tomorrow and I'm just getting started. If you're a WebStorm user, a JS/TS developer, or someone who thinks the IDE still has a role to play in an agentic development world, I'd genuinely love to hear from you. #WebStorm #JetBrains #DeveloperAdvocate #DevRel #TypeScript #JavaScript #DeveloperExperience

Jun 16, 2026

Newsletter

I Wasn't Even Looking. That's Why It Worked.

I've been watching the job market do something ugly lately. Layoffs. Hiring freezes. People with ten solid years of experience posting "Open to Work" and hearing nothing back for months. And I HAVE thoughts. Because I just went through a transition myself, Torc to JetBrains, and the way it happened directly contradicts some of the stuff conventional wisdom says about getting hired. I wasn't looking. 1. Why I Left (The Real Version) Let me be honest about something, because the polished career-change post isn't what this newsletter is for. I was on a contract at Torc. No benefits. I have kids. At a certain point, that math stops working no matter how much you love the work and I genuinely loved the work. taylor desseyn , my former boss and my partner in crime, is one of the best teachers I've had in this career. We talked about this stuff every single day. We built a community together that I'm proud of in a way I struggle to put into words. Leaving that was hard. It's still a little hard. We talk all the time but it's different you know how it is when you've built something real with someone and then you're just not in the building anymore. But I also had to be honest with myself. I never intended to be in staffing long term. I'm a developer at heart. Getting back to building, to code, to tools that developers actually use, that pull never went away. And then the interviews started happening, and I started seeing my own value reflected back at me in a way that made it clear: it was time to grow. Staying comfortable when you know it's time to move is its own kind of dishonesty. The hardest part wasn't finding a new job. It was accepting that it was okay to go. 2. The Always-Be-Interviewing Rule (No, Not What You Think) Here's something Taylor and I preached inside the Torc community constantly: interview even when you're happy. Not because you're disloyal. Not because you're restless. Because you cannot give honest advice about a job market you haven't been inside recently. If you're helping developers navigate their careers and you haven't sat across from a hiring manager in two years, you're just recycling old maps. So I interview. Apple, Laravel, PayPal, JetBrains. And here's what I want you to understand about how every single one of those conversations started: none of them came from a job board. None of them came from a recruiter cold email. Every one of them started with casual connections. Chatter on socials, showing up in the right spaces, being a real person (cue "i'm a real boy) in conversations that had nothing to do with employment. I didn't apply to any of these places until I had already spoken to someone on the inside. The relationship came first. The application came after. That's not a strategy I cooked up, it's just what happens when you've been consistently visible and genuinely present long enough that when a role opens up, someone thinks of you before the job post even goes live. And here's the wildly ironic part: the skills that got their attention were the ones I'd built at Torc ! The same ones we used every day to help other people get hired. People were coming for the exact thing I'd been building. I just hadn't been building it for them. 3. The 24-Hour Livestream That Changed Everything Last Christmas, I ran a 24-hour livestream. Jan-Niklas Wortmann from JetBrains was one of the participants. He didn't see a polished portfolio. He didn't read a carefully curated LinkedIn summary. He watched me work in real time, for hours, live. After that, he reached out and suggested I apply for a role on his team. I did. That is what "building in public" actually means — and it's something Taylor and I lived together. It is not posting your wins. It is not a brag thread. It is being so consistently visible doing the actual work that the right people eventually can't miss you. The stream wasn't a job-hunt strategy. It was just something I do. Because it's what we do. 4. The PayPal Decision (And What I Did With It) By the time the JetBrains process got moving, I already had a signed offer from PayPal on the table. And here's something a lot of people don't know they're allowed to do: I took that offer directly to JetBrains and was transparent about where I stood. I wasn't playing games. I told them the situation honestly I had an offer, I had a start date, and I was genuinely interested in their role. JetBrains responded by expediting my entire interview process to meet my deadline. They felt it was worth moving fast to find out. And it worked. The PayPal offer was real and we took it seriously. Hybrid role, three days a week in Austin, Texas. I live in New York. My uncle lives in Austin and had space for me to crash. We actually sat down and tried to make it work. We crunched the numbers, mapped out the flights, talked through what week to week would actually look like. And on paper you could almost convince yourself it was doable. But when we stopped trying to make it work on paper and started thinking about what it would actually feel like six months in. The burnout, the time away from my kids, the toll on my family, back and forth every single week (woof). It wasn't a logistics problem anymore. It was a quality of life problem. And no salary makes that math MATH when you're being honest about it. It was a genuinely hard choice. PayPal is a great company and it was a real opportunity. But hard doesn't mean wrong. JetBrains came in higher and 100% remote. But I want to be clear ...WE CONSIDERED IT. We just knew. The leverage only existed because I was transparent. I didn't hide the competing offer hoping to play both sides. I put it on the table honestly and let both companies make informed decisions. That's not a negotiation tactic. That's not a negotiation tactic. That's just being a straight shooter, and straight shooters tend to get treated like adults. 5. What This Has to Do With the Market You're In Right Now Here's what I keep watching: the people struggling hardest right now are the ones who only started building visibility when they needed a job. Starting from zero in the worst conditions, wondering why nobody is responding. The people landing in a brutal market are the ones who've been consistently showing their work not as a tactic, but as a practice. The campfire has to be burning before you need people to show up. Also, I want to be specific about what I mean by that, because "build in public" has become its own kind of empty advice. I'm not talking about posting. I'm talking about a track record. Real people who have watched you work, over time, showing up in the same spaces, doing the thing repeatedly not just announcing it. Jan-Niklas saw a 24-hour stream and watched me actually do the work. The folks at Apple, Laravel, PayPal.... none of those conversations started with me applying. They started because people I had been in rooms with, real and virtual, already knew what I was about before I ever sent a resume. That's the network that matters. Not the follower count. Not the connection requests. The people who have watched you long enough to vouch for you without being asked. If you're waiting until you're unemployed to become visible, you're already behind. If you're only interviewing when you have to, you don't actually know what the market values right now. And if you're only building in public when you have something to announce that's not building in public. That's a press release. The track record is the asset. Start building it before you need it. The Bottom Line: You don't need to be looking to be findable. Interview when you're comfortable so you know what comfortable actually means. Build in public as a standard, not a strategy. Be transparent in your process with companies, with your network, with yourself. And when it's time to grow, give yourself permission to go even when what you're leaving actually mattered. Especially then. Shoutout to Taylor Desseyn. Everything I'm describing in this newsletter, we talked about at a campfire you helped build. I'm just carrying the fire somewhere new. This week's question: Are you interviewing right now ? even if you're not looking? When's the last time you did? Hit reply. A human who has thought about this way too much will actually read it.

Mar 31, 2026

Newsletter

Hey, you’re a Data Pro, So Why Does Your Resume Suck at Data?

Welp, I just got back from DataTune 2026, and you are NOT gonna believe this, but I HAVE some thoughts. It was my last in-person event before moving on to my next chapter, and we spent the time doing back-to-back resume reviews. After looking at dozens of profiles, I noticed one blaringly obvious, borderline ironic theme: People who get paid to analyze and pull data for a living are absolutely terrible at giving data about themselves. 1. The Cobbler’s Shoes (Data Edition) It’s the classic "cobbler’s children have no shoes" scenario. We saw brilliant data engineers and analysts who can build complex pipelines and beautiful dashboards, yet their resumes were a desert of vague bullet points like "Responsible for data analysis" or "Collaborated with stakeholders." If you can’t quantify your own impact, why should a hiring manager trust you to quantify their business? In a world of AI slop, a resume without hard data is just noise. 2. The Kelsey Hightower Formula: Action > Impact It reminds me of a great conversation I had with Kelsey Hightower when he came and did resume reviews with me once. He put it quite succinctly: "Action > Impact." It’s a simple, high-value framework: what did you actually do, and what was the specific result? If you aren't connecting your daily tasks to a measurable outcome, you're missing the "gold" in your history. It’s the ultimate way to put data points in a resume that actually mean something to a human on the other side. 3. Stop Being Vague, Start Being "Necessary" We talk a lot about Ikigai—that intersection of what you love and what the world needs. Right now, the world needs people who can prove their value with evidence. Whether you’re at the beginning, middle, or end of your journey, your resume needs to reflect the "Kintsugi gold" of your career—the specific, data-backed wins that make you unique. Don't say: "Improved database performance." Do say: "Reduced query latency by 40% using [Specific Tool], saving the team 10 hours of manual labor per week." 4. This is Why the Torc Community Matters This irony is exactly why we lean so hard into our community reviews. Sometimes you’re too close to your own "onion" to peel it back properly. You need a peer—someone at the campfire—to look at your work and say, "Hey, you forgot to mention that you saved the company $50k last quarter." At Randstad Digital | Torc , we aren’t just a megaphone for jobs; we’re a relationship engine designed to help you upscale and present the best, most data-driven version of yourself. The Bottom Line: The tech landscape is shifting, and "gliding through with military precision" isn't enough anymore. You need to be your own best data analyst. At the end of the day, no matter what part of the journey you are on—whether you're just starting out, grinding through the middle, or looking for your next big exit—there is always a community here for you at Torc. Don't let your resume be "AI slop." Head over to the Torc Discord, drop your resume in the review channel, and let’s help you find the gold in your cracks. What’s one metric from your current job you’re actually proud of? Hit reply and tell me—I promise a human (who loves data) will read it.

Mar 10, 2026

Newsletter

Nobody Learns Anything From a Hot Take

There's a content format that's taken over Developer Relations LinkedIn and I can't stop watching it burn. You know the one. "Things people say in DevRel vs. what they actually mean.🔥" "Here's why your conference budget is completely wasted.💰" "Unpopular opinion: most DevRel teams shouldn't exist.🥑" The comments go crazy. Practitioners either nod furiously or get defensive. Someone writes "this is exactly my situation." Someone else writes "this is reductive and you clearly don't understand enterprise Developer Relations." The poster responds to both with "love the discussion, this is why I post." Nobody fixes anything. Nobody learns anything. The cycle repeats next week with a slightly different hook. 1. The irony is almost too good The whole premise of this content is that Developer Relations has a measurement problem. Companies chase vanity metrics — t-shirt pickups at a conference booth, Discord MAUs, blog views — instead of asking whether any of it actually moved the product forward. But the posts criticizing this behavior are themselves vanity metrics plays. Engineered for maximum reaction, minimum accountability. The "engagement" they generate is the same thing they're criticizing: people feeling something, then going back to doing exactly what they were doing before they opened the app. "Our docs are comprehensive." Translation: our docs are 400 pages and nobody can find the quick start. The comment section lights up. 800 reactions. "This is literally my company lol." The poster writes a follow-up next week about something else that's broken. Nobody updated the docs. 2. A hot take is not a diagnosis "Your conference strategy is a $40K mailing list" might be true. But the response to that isn't a witty post — it's sitting down with whoever approved the spend and asking what success was supposed to look like before the booth got bought. Hot takes describe symptoms. They don't do the hard work of finding the root cause, and they definitely don't stick around for the fix. 3. The discourse has the same problem as the thing it's criticizing Here's what I keep coming back to: the Developer Relations industry has a strategy problem. Companies hire Developer Relations reactively. They measure it wrong, or don't measure it at all. They wonder why it's not moving a number nobody named in the first place. The LinkedIn content about this problem has the exact same structure. Posted reactively. Optimized for engagement over outcomes. No agreement on what "useful" looks like before it goes out. I've shipped enough content to know this pattern from the inside. It feels like work. It has metrics. It is not the same as being useful. 4. What actually useful looks like A useful post about conference strategy would include: how one team defined success criteria before buying the booth, what they tracked during the event, and what they changed the next time. That post gets 40 likes. The hot take version gets 400. That gap is the whole problem. If you want to fix Developer Relations , pick one thing, go one level deeper than "here's what's broken," and tell me what you actually changed. I will read that every time. This week's question: Have you ever actually changed something at work because of a LinkedIn post? I'm genuinely asking. Hit reply.

Mar 04, 2026

Newsletter