Arkitekturvalg, der rent faktisk betyder noget
De fleste arkitekturdiagrammer er pynt. Fem beslutninger flytter reelt nålen på pris, hastighed og overlevelsesevne. Resten er smag.
De fem beslutninger, der betyder noget
Det meste af det, der kaldes arkitektur, er rent faktisk præference. Fem beslutninger former reelt et systems pris, hastighed og levetid. Få dem rigtige, og de fleste andre valg bliver gendannelige. Få dem forkert, og intet framework-valg vil redde dig.
- Deploy-unitten. Én service eller mange. Det er en envejsdør i årevis.
- Datamodellen. Formen på dine tabeller afgør, hvilke forespørgsler der er billige, og hvilke funktioner der overhovedet er mulige.
- Transaktionsgrænsen. Hvad der må være inkonsistent, hvor længe, og hvor brugeren ser det.
- Integrationsgrænsen. Hvor du stoler på andre systemer, og hvor du ikke gør, og hvad du gør, når de er nede.
- Sletteplanen. Hvordan du fjerner en del af systemet. Kan du ikke svare på det, samler du juridiske byrder.
Database-valget (og det kedelige svar)
For 95 % af nye systemer er den rigtige database Postgres. Det er ikke et mode-statement. Det er i 2026 den mest underbrugte database blandt teams, der stadig vælger noget andet som standard.
Postgres giver dig transaktioner, joins, JSONB til de dele du rent faktisk vil have skemaløse, partielle indekser, materialized views, full-text-søgning, listen/notify, row-level security og en kø-tabel, der vil overleve tre af dine microservices. Den operationelle historie er velforstået af hver senior backend-udvikler i Europa.
Vælg noget andet, kun når workloaden reelt ikke passer: meget høj write-throughput på tidsseriedata (Timescale, Clickhouse), reelle document-store-behov uden relationel hale (MongoDB), realtidsbaseret samarbejdsstate (Convex), eller vektorsøgning i skala (et dedikeret indeks, ikke dit primære store).
Én deploy-unit, indtil andet er bevist
Den enkelt dyreste arkitektoniske beslutning, teams træffer, er at splitte et system op i services, før de er nødt til det. Microservices-samtalen hører hjemme i sit eget essay, men tommelfingerreglen er simpel: hvis du ikke har flere teams, der ejer slices fra start til slut inklusive on-call, så har du ikke organisationen til microservices.
En modulær monolit med eksplicitte modulgrænser giver dig 80 % af de fordele, folk vil have fra microservices, til 10 % af driftsomkostningen. Når dagen kommer, hvor du reelt skal udtrække en service, udtrækker du et modul. Grænsen er der allerede.
Kedeligt er ikke det samme som usofistikeret. Kedeligt er det, der overlever den udvikler, som valgte det.
Transaktioner og konsistens
Eventual consistency er ikke en gratis arkitektonisk funktion. Det er et UX-problem, du har flyttet væk fra databasen og over på brugeren. Hver "kurven er tom i tre sekunder, efter jeg lagde noget i" er en arkitektonisk beslutning, som brugeren betaler for.
Vælg som standard stærk konsistens inde i én deploy-unit. Ræk efter eventual consistency, kun når latency, skala eller geografi reelt kræver det, og når produkt har accepteret skriftligt, at inkonsistensen er acceptabel i det brugervendte flow.
Baggrundsarbejde og køer
En kø-tabel i din eksisterende database er en seriøs primitiv. SELECT FOR UPDATE SKIP LOCKED på Postgres håndterer titusinder af jobs i sekundet på hardware, der intet koster. Du får transaktionel enqueue sammen med resten af din write, ingen ekstra infrastruktur, ingen anden kilde til sandheden.
Ræk efter en rigtig broker (Kafka, NATS, Pub/Sub, SQS), når du har brug for fan-out til flere uafhængige consumers, når én kø ville være et flaskehalspunkt på tværs af teams, eller når du har brug for replay-semantik. Ikke før.
Caching er gæld med en hit rate
Hvert cache-lag du tilføjer er en ny fejltilstand: stale reads, thundering herds, invalideringsbugs, kold-cache-hændelsen når cache-flåden genstarter. Tilføj caching, kun når du har et målt latency- eller load-problem, ikke fordi du læste et blogindlæg.
Når du tilføjer en cache, så skriv invalideringsplanen først. Kan du ikke formulere, hvornår en entry fjernes, er din cache en feature flag for at servere forkerte data.
Integrationsgrænser (og on-call-historien)
Hvert eksternt system, du afhænger af, bliver en del af din uptime-historie. Stripe, dit CRM, dit CMS, din auth-provider, din analyse — når de er nede, er du nede, medmindre du har skrevet fallbacken.
- Behandl tredjepartskald, som om de vil time ud, prøve igen, fyre dobbelt og rate-limite. Fordi de vil.
- Pak dem ind i en tynd adapter, så du kan udskifte dem eller stubbe dem i tests.
- Beslut eksplicit, hvad din app gør, når hver af dem er utilgængelig. Skriv det ned.
- Cache de svar, du kan. Idempotency-keys på de writes, du ikke kan.
Vil du have denne slags vurdering på dit projekt?
Jeg læser hver e-mail inden for én arbejdsdag. Tag et projekt, et tilbud eller et system, du sidder fast i.
15 ting hvert Contentful enterprise-projekt får galt i de første 6 uger
De 15 produktions-huller hvert enterprise Contentful + Next.js-build rammer i de første seks uger — og hvordan du lukker hver enkelt uden at brænde et sprint. En pre-kickoff-checkliste til tech-leads på en Contentful enterprise starter.
REST + GraphQL-hybrider til multi-locale CMS-drevne sites
Hvorfor hverken kun REST eller kun GraphQL er det rigtige valg til et enterprise multi-locale CMS-site, og hvordan du splitter efter ansvar i stedet. Inkluderer cirkulære referencer på fulde REST-payloads, bundle-omkostningen ved GraphQL på klienten, beslutningsmatricen pr. kaldsted, den samlede fetcher, granulære cache-tags, blok-som-fragment-mønsteret, locale-fallback i ét round-trip, Live Preview der overlever, Server Actions til CMA-skrivninger, Algolia Sync API-undtagelsen og migrationsrækkefølgen.
Konsulent-playbook'en
Sådan fungerer digitale bureauer, sådan prissætter de, og her er, hvor danske kunder typisk betaler for meget.