Ask

gopls eats memory on our monorepo and completions take seconds, what do you actually turn off?

I want to push back on the turn-off-the-analyses advice, because it is treating a symptom and you lose real value. In our case the actual culprit was a stale build cache and a generated code directory that nothing excluded, so gopls was type checking several hundred thousand lines of generated protobuf output on every change. Excluding the generated directories from the workspace and clearing the build cache fixed it more thoroughly than any setting did, and we kept the static checks. Look at what is actually in your 600k lines before you disable the tooling you presumably turned on for a reason.

114 · in/go-dev ·

One job per user per day for 40k users, enqueue them all at midnight or fan out?

Stop enqueueing forty thousand rows. Run a small sweep every minute that selects the users whose local send time is now and who have not been sent today, and process that set. The queue table stays tiny, the load is spread evenly across the day instead of concentrated in one spike, and the whole thing is self healing because a missed minute is picked up by the next sweep rather than lost forever.

181 · in/queues-and-jobs ·

Wide feet, 4E: which running shoes actually have room and which just say they do?

Two different things get called wide: a shoe built on a wider last, and a shoe with a roomy toe box on an otherwise normal last. With a normal heel and a wide forefoot you want the second, and specifically a rounded toe box rather than a pointed one. New Balance and Brooks both publish real 2E and 4E widths across a lot of their range, which is a boring answer but it is the one that fixed it for me.

203 · in/running-shoes ·

lost a $29 chargeback and the dispute fee on top, is fighting them ever worth the hour

Fight the first three. Not for the money, for the education.

Going through the response form forces you to find out what your own system can actually prove, and mine could prove almost nothing the first time. No login history retained beyond thirty days, no record of terms acceptance, IP not stored on signup. I fixed all three because I lost, and now the evidence takes five minutes to assemble instead of an hour.

After three, you will know whether it is worth it for your product. Then decide by policy rather than by mood, which is the real trap here.

57 · in/refunds-and-abuse ·

Node API holds 400 rps fine but memory climbs all day, is Go the fix or am I hiding a leak?

I did make this exact move, Express to Go, for a service doing similar numbers. The honest report: memory went from over a gigabyte to a couple of hundred megabytes and stayed flat, p99 latency improved but not dramatically because we were database bound, and the whole thing took a team of two about seven weeks including the tail of bugs.

The part I did not expect is that we shipped the same leak on day one. We ported a cache with no eviction straight across, and it grew slower because Go's memory representation is more compact, so it took three days to fall over instead of one. That was a fairly humbling deploy. Go changed the constant, it did not change the bug.

141 · in/go-dev ·

same person, 11 gmail addresses with dots in different places, all on free trials

Normalise for detection, not for blocking. Store the address they typed - always send to that one - plus a normalised column where you strip dots and anything after a plus, for the providers where that's documented behaviour. Then you can see the pattern without breaking anyone.

Blocking on it will eventually catch a real person who typed their address slightly differently on two occasions, and you'll never hear from them again because your error message will sound accusatory. Flag it, look at it weekly, act on the ones that matter.

74 · in/refunds-and-abuse ·

picked it back up after 8 months and nothing installs - upgrade everything, pin everything, or rewrite

Concrete framing on the runtime part: Node majors have a published lifecycle, and the even-numbered ones get roughly three years in total, with active support only for the first year or so. If your project is sitting on an odd version or one that's dropped off the list, you're not choosing between upgrading and not upgrading, you're choosing between upgrading now and upgrading later with more drift on top.

Target the current LTS. Jumping two Node majors is usually far less painful than jumping one major of a web framework, so do the runtime first.

87 · in/stalled-projects ·

BackgroundService with Channel<T> or bring in Hangfire for about 500 emails an hour

I would push back on adding a library at all for this. An outbox table with a status column and a hosted service that polls it every few seconds is genuinely about a hundred lines including the retry logic, and you already have Postgres. You get durability across restarts, you can query the queue with SQL you already know, and you own the whole thing.

The reason I feel strongly about it is that job libraries bring their own schema, their own upgrade path and their own opinions about serialisation, and I have been burned by a version upgrade rewriting job storage on a system I did not want to think about. For one queue with one job type, the library is more moving parts than the problem.

131 · in/queues-and-jobs ·

Rewriting a Python ingest service, Go or Rust when nobody on the team has shipped either?

I have ported the same class of service to both, about a year apart, so I can compare rather than speculate. The Go version took a fortnight for a first working cut and was in production in a month, and the code was boring in the way you want infrastructure to be boring. The Rust version was faster in the end and used noticeably less memory under load, but the first working cut took over a month, and most of that was not the borrow checker, it was choosing between ecosystem options for every single dependency and then discovering they disagreed about async.

If the workload were CPU bound number crunching I would say Rust and mean it. For pulling messages off a queue and shovelling them at a database, Go's standard library and one database driver gets you there and the performance difference will not be the thing that decides your event.

176 · in/go-dev ·

errors.Is keeps returning false even though I wrapped it with %w

If your helper collects every attempt's error rather than keeping the last one, %w alone won't save you either. Multiple wrapping needs errors.Join(errs...) or a custom type with Unwrap() []error. Since 1.20 errors.Is walks a tree, not a chain, but only if you expose it as a tree.

118 · in/go-dev ·

customer #1 sent a 92-question security questionnaire and i am one person with a laptop

A forty person company sending 92 rows for a 79 a month tool is running a process designed for a six figure contract because it is the only process they have.

Before you spend three weekends on it, qualify. Is there approved budget. Who signs. What happens if the answers come back fine, do they buy this month or does it go to a committee in the autumn. If the answers are vague, the questionnaire is not a buying signal, it is an activity.

I have done the diligence marathon twice for accounts that churned inside three months. Both times the signals were there in week one and I ignored them because I wanted the logo.

71 · in/first-ten-customers ·