Software Engineer Cover Letter: Evidence, Not Adjectives
Most engineering applications are decided on your resume, your code, and your interviews. The cover letter is rarely the deciding artifact. Write one anyway when it can carry something a resume cannot: a technical decision you made and why, a real reason for this team, or the logic behind an unusual path.
The skepticism is reasonable, and where it breaks down
Engineers distrust cover letters for a defensible reason. The rest of the pipeline is made of inspectable artifacts. A repository can be read, a take-home can be run, a systems design round exposes how you think under questioning. Against that, a page of prose looks like the weakest signal available, and most advice about it makes things worse by recommending enthusiasm where evidence belongs. At a large company with a structured loop, your letter may well sit in a field nobody expands. We looked at how unevenly this varies in do employers read cover letters; the short version is that no honest source can give you a percentage.
Where the skepticism breaks down is in treating "usually not decisive" as "never useful". A resume is a compressed format. It can say you owned a service. It cannot say you inherited a nightly job that kept double-crediting refunds, or what you replaced it with. Some applications turn entirely on that gap:
- The hiring manager is screening personally, which is normal below roughly fifty engineers.
- You are missing something the posting lists, and would rather address it than be filtered silently.
- Your stack does not match theirs, but the underlying problem does.
- You are switching domains, self-taught or bootcamp-trained, or returning after a break.
- The team runs on design docs, so your letter is a writing sample whether they say so or not.
- The posting requires one. Skipping it is a procedural cut, not a judgment call.
A cover letter will not rescue a weak application. It occasionally explains a strong one that the resume was quietly misrepresenting.
Replace every adjective with a decision
The failure mode in engineering letters is not bad writing. It is describing qualities instead of work. "Passionate about scalable systems" is unfalsifiable, so it carries no information, so a technical reader skips it. For each claim, ask what you did, what the constraint was, and what changed afterwards.
I am a passionate backend engineer with strong experience in distributed systems and a proven track record of delivering scalable, high-quality solutions. I thrive on solving complex problems and am highly skilled in Go, Postgres, and Kubernetes.
Our settlement service was double-crediting refunds whenever a Kafka partition rebalanced mid-retry. I added an idempotency table keyed on (merchant_id, external_ref) and moved the settlement write behind a single transactional boundary. Duplicate credits went from a weekly manual cleanup to none.
The second version never claims to be good at distributed systems. It demonstrates a working mental model of one in three sentences, using a failure mode a reader either recognises or does not. Nobody needs to be told your skill level; they infer it from how precisely you describe a problem.
Two rules keep this honest. Use numbers you can defend in an interview, because you will be asked to. And if you were one of six people on a project, write "I worked on" rather than "I built". An interviewer who finds you overstated your scope stops believing the rest of the letter.
Engage with what the team is actually building
"I am excited about your mission" is the prose equivalent of a null check that never fires. What works is one specific observation about their technical situation, followed by a real question. Read their engineering blog, conference talks, open-source repositories, public API and changelog, and the architecture implied by the posting. You are looking for a decision they made that you have an opinion about.
Your post on splitting the shared ledger into per-merchant balances describes the same fan-out problem we hit at smaller scale, and you resolved it in the opposite direction from us. I would want to understand how cross-merchant transfers behave during a shard rebalance, because that was the case that kept us on a single ledger.
That flatters nobody. It signals that you read their material, understood it well enough to disagree, and would be useful in a design review. If you cannot find anything real to say, cut the paragraph. Three honest paragraphs beat four padded with admiration.
A full worked letter: senior backend engineer
Fictional company, fictional candidate, real structure. The posting emphasises idempotency, settlement correctness, and a planned move from Go to Rust in the core.
Dear Hiring Manager,
For the past three years I have owned the ledger and settlement services at Bramwell Retail, where we process around forty thousand card transactions a day across eleven markets. Your posting leads with exactly-once settlement and idempotency, which is where most of those three years went.
The work I would point to first: we were double-crediting a small number of refunds, always during Kafka partition rebalances, and it had twice been dismissed as a reporting bug. I traced it to an at-least-once handler that treated the ledger write and the outbox insert as separate operations. I introduced an idempotency table keyed on (merchant_id, external_ref), collapsed the two writes into one transaction with a transactional outbox, and replaced the nightly reconciliation batch with a streaming job. Duplicate credits stopped, and reconciliation lag went from roughly fourteen hours to under five minutes.
I read your post on moving from a shared ledger to per-merchant sharded balances. We looked at the same split and stayed monolithic, mostly because cross-merchant transfers during a rebalance were a case we could not make safe on our timeline. I would genuinely like to know how you handled it.
On stack: I work daily in Go and Postgres, run and debug my own services on Kubernetes, and have done enough on-call to have opinions about alert design. Your core rewrite is in Rust. I read Rust comfortably and have used it on side projects, but I have not shipped it in production, so I would expect a real ramp there.
Happy to walk through the settlement migration in detail, including the parts we got wrong first.
Elena Vasquez
Paragraph by paragraph: scale, matched against the posting's own first priority; one technical story with a diagnosis and a consequence; engagement with their published thinking; and the stack gap stated plainly rather than hidden. Nothing in it would embarrass the writer in a follow-up interview.
Do not paste your resume into paragraph form
If the letter restates your bullet points, a reader who already has your resume gains nothing. One story told properly beats a summary of six. Pick the project closest to what the posting asks for and spend the whole middle of the letter on it.
What changes for frontend, ML, and platform roles
The structure holds across engineering. The evidence you lead with does not.
| Role | Lead your evidence with | Common miss |
|---|---|---|
| Backend | Failure modes under load: an incident and the invariant you introduced | Listing services owned without saying what was hard about them |
| Frontend | Something they can look at, plus a measured user-facing outcome: bundle size, interaction latency, a rendering or accessibility bug class you eliminated | Naming frameworks instead of outcomes. React on the resume already says React. |
| ML / data | Problem framing and evaluation rather than architecture: what you measured, the baseline, how it behaved on real traffic | Offline metrics with no mention of deployment, drift, or data quality |
| Platform / infra | Blast radius reduced, toil removed, a migration finished without an outage | Tool lists. Terraform and Kubernetes are table stakes; judgment is the signal. |
For frontend roles, link the thing: a portfolio URL, a deployed project, a merged pull request. One link that resolves does more than a paragraph describing it. For ML roles, be careful with numbers, since a lift figure with no baseline reads as noise to anyone who has run an experiment.
Startup versus large company
At a startup, the letter is likely to be read, often by someone who will interview you. Breadth and ownership are the currency: what you shipped end to end, what you ran without supervision, what you are willing to pick up. Being specific about why this company matters more here, because small teams are trying to separate people who want this problem from people sending four hundred applications. Two or three tight paragraphs is right.
At a large company, assume the letter is optional and may not be opened. Put your effort into the resume first, since that is what gets searched and filtered against the posting's terminology; the mechanics are in our guide on tailoring a resume to a job description. Then write a short letter anyway: four or five sentences naming the team or product, the closest system you have worked on, and one result. Letters do get read far more often for internal transfers, returning employees, and referred candidates, where a human is already looking at your file rather than at a queue.
Where the letter carries the most weight
If you are a switcher, self-taught, a bootcamp graduate, or returning after a break, the letter stops being optional. Your resume presents a discontinuity, and a screener with a stack of applications will supply their own explanation if you do not supply yours. Theirs is usually less generous than the truth. What works is a plain narrative connecting the two halves, carrying evidence from the new half. What does not work is apology, or claiming the old career was secretly software engineering all along.
I spent six years as a clinical laboratory scientist before moving into software, and I am applying to a diagnostics platform rather than anywhere else because I have been the person on the other end of a bad LIMS integration at 2am. Since retraining I have spent eighteen months as a backend engineer at Halden Health, where I rebuilt our HL7 ingestion pipeline after it silently dropped results whose segment order varied by analyser. I wrote a fuzzer for the parser, fixed the ordering assumptions, and added a reconciliation check that has caught four upstream vendor changes since.
That paragraph names the switch without defensiveness, gives a reason for this employer only this candidate could give, and produces engineering evidence from the new career. The old career becomes domain knowledge, which is what it actually is. New graduates have a related problem, since coursework has to read as engineering work rather than as assignments; that is covered in our new grad cover letter guide, and the structure underneath all of this lives in how to write a cover letter.
A short check before you send
- Every adjective about yourself is gone or replaced with something that happened.
- One technical story has a diagnosis, a decision, and a consequence.
- Something in it could only have been written for this company.
- Any number is one you can reconstruct under questioning.
- Gaps and stack mismatches are stated plainly rather than avoided.
- The company name is right everywhere, including in the file name.
Keep the per-application cost low
Engineers stop writing letters because of time, not principle. Ninety minutes per application does not survive contact with a real search. Keep one strong base letter and rewrite the opening and the middle story for each posting. If you want the first draft handled, SwiftCover turns a pasted posting into a tailored letter and matching resume in about thirty seconds, all of it editable before export. The editing pass is still yours, because specificity is the part no tool can invent for you.

