· 7 min read

The backend developer costume

Programmers turn languages and job titles into moral ranks because managed cloud primitives have made ordinary application backends embarrassingly small, and the resulting status theater distorts hiring, reviews, and architecture.

Paul Cézanne’s painting of Pierrot in white and Harlequin in a diamond-patterned costume standing beside one another before a curtain.
Paul Cézanne, Public domain

I watched a code review spend forty minutes deciding whether a TypeScript service made the team look unserious. The change added one nullable column, copied it into a JSON response, and had already passed every test. Nobody discussed the migration.

The endpoint had become a referendum on what kind of people we wanted to be. Rust would mean discipline, Haskell intelligence, Go pragmatism, Java enterprise adulthood, and PHP a failure to escape 2009. A programming language is a toolchain, not a character reference.

We keep using languages that way because identity fills the space left when the work becomes ordinary. Cloud platforms have moved an enormous amount of difficult engineering below an API, so a large share of commercial backend development now consists of authentication, a database, a few handlers, and a queue somebody else operates. Rather than enjoy the victory, we dress the remaining glue in job titles and argue about which syntax proves we deserve them.

The compiler became a horoscope#

Henri Tajfel and his colleagues found that boys assigned to arbitrary groups could favor their own group while allocating rewards, even when the categorization carried almost no history or material stake. Their 1971 minimal-group experiments used trivial distinctions such as supposed painting preferences. Tajfel studied schoolboys, so the analogy has limits; the mechanism still looks painfully familiar once the group names become Rustaceans, Gophers, Pythonistas, and functional programmers.

Language communities start from something valuable. A real community of practice lets people exchange techniques, preserve hard-won stories, review one another's work, and teach newcomers how recurring problems are handled. The trouble begins when shared practice hardens into shared virtue, then every outsider becomes evidence that standards are slipping.

We even publish a yearly table of affection. The 2025 Stack Overflow survey calls one section “Admired and Desired” and reports Rust as the most admired language at 72 percent. The survey asks whether people who used a technology want to continue; our arguments often upgrade that preference into a ranking of the people who use it.

Actual comparisons keep producing conditional answers. Nanz and Furia's Rosetta Code study found different winners for concision, large-input speed, and runtime failures. A later reanalysis of language and code-quality data found statistically significant defect associations for only four languages, with exceedingly small effects, while a study of maintainability prejudices found most of its language stereotypes unsupported, including the claim that JavaScript code was worse than the rest. The studies leave language choice as one technical variable among many and give us little basis for rating the person who wrote the repository.

The machine room moved downstairs#

Managed cloud products describe the compression without embarrassment. Supabase puts one Postgres database at the center, connects authentication to row-level security, and uses PostgREST to turn the database directly into a REST API. Firebase sells authentication, managed relational and document databases, object storage, hosting, and backend functions without server management from the same product page.

This is good engineering. Thousands of teams can inherit replication, TLS, token verification, process replacement, backups, and global delivery instead of rebuilding them badly. The amount of custom application code left for an ordinary create endpoint can look like this:

create-note.tsts
export async function POST(request: Request) {  const user = await requireUser(request);  const input = CreateNote.parse(await request.json());  const [note] = await db    .insert(notes)    .values({ ownerId: user.id, body: input.body })    .returning();  return Response.json(note, { status: 201 });}

For fuck's sake, it is a table with an authorization rule. We can call the function a service, put it behind an API gateway, add three tracing headers, and give its owner a backend title, but the handwritten path still runs from authentication to INSERT and back.

The code stays small because the provider carries machinery beneath it. Product teams still own every decision whose failure reaches a customer, and those decisions have merely become easier to overlook when the infrastructure arrives preassembled.

ConcernManaged layer carriesApplication team still decides
IdentityAuth provider issues and verifies tokensWho may read, create, change, or delete each record
PersistencePostgres or Firestore stores and replicates dataSchema, constraints, migrations, and retention
ExecutionFunctions or containers run on managed infrastructureRetries, idempotency, timeouts, and side effects
OperationsPlatform patches machines and replaces failed instancesObservability, incident recovery, capacity, and cost
Managed products move implementation downward while application policy stays with the team.

I haven't counted every backend, and the exceptions are substantial: database engines, compilers, payment ledgers, media pipelines, low-latency trading systems, and infrastructure products still contain hard systems work. This rant targets ordinary product software, where complexity usually comes from policy, data history, and changing requirements rather than from moving bytes between machines.

The badge starts designing the system#

Once a role becomes a source of dignity, the architecture starts reserving territory for it. A developer who wants to become a Rust developer can find a service boundary by lunch. A backend team protecting its status can turn one new profile field into an API ticket, a schema copy, a release dependency, and a meeting about ownership.

The same sorting reaches hiring. A careful developer with ten years of PHP gets read as someone who survived a bad ecosystem, while a newcomer carrying a fashionable language receives credit for the language's values before demonstrating any of them. Then code review follows the hierarchy: reviewers praise iterator choices and lifetime elegance while the migration remains irreversible, the permission check sits in the client, and retries can charge the card twice.

I opened a repository last month called backend-platform expecting scheduling, isolation, or at least a stubborn distributed-system problem. Its only handwritten request path verified an Auth0 token, called a hosted Postgres database, wrote an object to S3, and returned a signed URL. The name was sincere; the difficult machinery belonged to four vendors.

Threats to the role feel personal because the role has become personal. A qualitative study of occupational identity among software engineers using generative AI found engineers engaging in identity-protective sense-making as automation pressed on competence, autonomy, and belonging. Cloud abstraction applies an older version of the same pressure: when the provider performs the machine work, the title has to find another reason to remain prestigious.

Teams pay for that defense through unnecessary rewrites, narrow hiring funnels, and boundaries drawn around prestige instead of change. Polyglot systems can be the right answer when workloads truly differ. They become exhausting when each service exists as a flag planted by the person who wanted a different identity on their conference badge.

The boring work is the job#

The cloud leaves plenty of engineering behind, but most of it photographs badly. Someone has to decide which facts deserve a durable column, which operations must be idempotent, how permissions compose, what a partial migration means, how old data gets repaired, and which alert wakes a human. These decisions become hard when real users, old data, existing integrations, and partial failures constrain every change.

The 2025 Stack Overflow survey makes the daily workload harder to mistake. Databases and SQL touch far more professional developers than the language at the center of many prestige arguments.

SQL61.3%
PostgreSQL58.2%
Rust14.5%
Technology use among professional developers in the 2025 Stack Overflow survey
SQL61.3%
PostgreSQL58.2%
Rust14.5%
Reported use among professional developers in the 2025 Stack Overflow survey.

A careful PHP developer who adds the unique constraint, rehearses the rollback, and checks the authorization boundary is doing better engineering than a careless Rust developer who models the request beautifully and duplicates every payment after a timeout. Type systems and runtimes can prevent entire classes of mistakes, which is a wonderful reason to choose them. The compiler still has no visibility into the migration plan or the production history that makes the change dangerous.

“Backend developer” remains a useful label when it tells a team who owns data integrity, service behavior, and production recovery. As a caste, it encourages people to defend a layer whose most important machinery may already belong to AWS, Google, Cloudflare, or a Postgres operator. In that version of the role, teams keep API boundaries and service ownership long after the architecture stops needing them.

At 16:47, the payment worker retries after a timeout and creates the second invoice because the table has no unique key on the provider event. The Rust hoodie, Go gopher, and Haskell sticker stay draped over empty chairs while someone opens psql, locks the bad rows, and writes the constraint everyone skipped during the argument about what kind of developer belonged in the repository.