13 ottobre 2026

System Design “da senior”: un framework pratico in 5 step per non perdersi tra requisiti vaghi e trade-off

Non basta disegnare scatole: nelle sessioni di system design contano metodo, comunicazione, giudizio tecnico e gestione del tempo.

Un framework operativo in 5 step per affrontare esercizi e colloqui di system design: come chiarire requisiti, definire data model e API, costruire l’architettura, ragionare su scalabilità e failure mode, e chiudere con trade-off ed estensioni. Include anche le 5 dimensioni su cui spesso si viene valutati oltre al “disegno” finale.

Nel system design la difficoltà non è “trovare la risposta giusta”. È dare una forma a un problema volutamente incompleto, prendere decisioni motivate sotto pressione e mantenere il controllo della conversazione (e del tempo). In altre parole: serve un metodo ripetibile.

Molti preparano questi round memorizzando architetture-tipo (messaggistica, streaming, marketplace). Aiuta, ma non basta: nella pratica vieni valutato anche su come comunichi, come strutturi il ragionamento e quanto sei pratico nel prevedere cosa può rompersi.

Qui trovi un framework essenziale in 5 step che puoi applicare a qualunque esercizio “design X” (streaming musicale, booking, chat, feed, ecc.), più le 5 dimensioni su cui tipicamente si viene giudicati.


Perché il system design sembra più “vago” del coding

In un live coding classico hai input/output definiti: una firma di funzione, vincoli chiari, test mentalmente eseguibili. Nel system design succede l’opposto:

  • i requisiti sono intenzionalmente incompleti;
  • devi tu definire scope e priorità;
  • non esiste un’unica soluzione corretta;
  • conta più il processo decisionale che la lista di componenti.

Questa vaghezza è proprio il punto: simula il lavoro reale, dove il problema raramente arriva già “impacchettato”.


Le 5 dimensioni su cui vieni valutato (non solo l’architettura)

Prima del framework operativo, chiarisci una cosa: il diagramma finale è solo una parte del punteggio.

1) Comunicazione e collaborazione

  • Fai domande di chiarimento.
  • Espliciti assunzioni e le validi.
  • Allinei lo scope prima di costruire.

In pratica: sei una persona con cui è facile lavorare quando i requisiti non sono perfetti?

2) Pensiero strutturato

Un candidato forte rende visibile la scaletta mentale:

  • “Prima chiarisco requisiti, poi modello dati/API, poi architettura, poi scalabilità e failure mode”.

Saltare avanti e indietro trasmette incertezza (anche se le idee sono buone).

3) Giudizio tecnico

Ogni scelta dovrebbe avere un “perché” legato ai requisiti:

  • SQL vs NoSQL
  • cache sì/no e quale strategia
  • coda di messaggi: quando serve davvero

Non basta nominare tecnologie: devi motivare trade-off e alternative.

4) Profondità pratica

Qui si vede chi ha toccato produzione:

  • failure mode
  • single point of failure
  • backpressure
  • retry storm
  • consistenza vs disponibilità

Sono dettagli che non emergono se ti fermi alla teoria.

5) Time management

Round tipico: 45–60 minuti. Se passi 40 minuti su high-level e non arrivi a scalabilità/affidabilità, stai lasciando punti sul tavolo.

Allinearsi presto su dove approfondire (e “timeboxare” ogni sezione) è un segnale da senior.


Il framework in 5 step (timeboxed)

Assumiamo un colloquio da 60 minuti. L’obiettivo è restare organizzati e dimostrare controllo del processo.

  1. Chiarimento requisiti (5–10 min)
  2. Data model + API (15–20 min) (o invertibile con l’architettura)
  3. High-level architecture (15–20 min)
  4. Bottleneck, scala, affidabilità (5–10 min)
  5. Wrap-up: trade-off ed estensioni (2–5 min)

Nota: gli step 2 e 3 puoi invertirli. Scegli l’ordine che ti aiuta a ragionare meglio e mantienilo coerente.


1) Chiarisci requisiti: funzionali e non funzionali

È l’errore più comune: iniziare a disegnare prima di aver fissato lo scope.

Requisiti funzionali

Definisci:

  • casi d’uso principali (es. “riproduci brano”, “ricerca”, “playlist”);
  • cosa è esplicitamente out of scope (in 60 minuti non progetti “tutto Spotify”);
  • tipologia di utenti e piattaforme (web, mobile, desktop);
  • scenari principali di lettura/scrittura.

Requisiti non funzionali

Fai emergere vincoli misurabili:

  • DAU/MAU, picchi, concorrenza;
  • read/write ratio;
  • target di latenza;
  • disponibilità/downtime accettabile;
  • consistenza richiesta (forte vs eventuale) per i dati critici.

Check-in consigliato: chiudi questa fase con una domanda di allineamento: “Questi requisiti e questo scope vanno bene prima che passi al design?”. Se manca qualcosa, spesso qui arrivano hint utili.


2) Data model e contratti API: cosa salvi e come lo esponi

Questa fase serve a rendere concreto il sistema: quali entità esistono e come dialogano i client.

Data model

  • Identifica le entità principali (es. User, Video, Message, Booking).
  • Relazioni e cardinalità.
  • Chiavi primarie/esterne o chiavi di partizionamento (a seconda dello storage).
  • Indici che impattano le query “hot”.
  • Stima della crescita dei record e dei campi “a rischio esplosione”.

Qui è un buon punto per dichiarare dove vuoi strong consistency e dove puoi accettare eventual consistency.

API design

Definisci endpoint essenziali (REST o altro) con:

  • request/response shape;
  • paginazione (cursor-based spesso batte offset a grandi volumi);
  • error handling coerente;
  • rate limiting;
  • versioning.

E soprattutto: scegli il tipo di database e motivane i trade-off rispetto ai requisiti (non “perché lo conosco”).


3) High-level architecture: componenti e flussi end-to-end

Qui disegni i blocchi principali e fai walkthrough dei flussi principali (read e write).

Se sei in difficoltà, parti da quattro mattoni quasi universali:

  • Load balancer
  • API servers
  • Database
  • Cache (opzionale, ma spesso decisiva)

Poi aggiungi quando servono:

  • message queue / event bus per decoupling e lavoro asincrono;
  • servizi dedicati (search, media processing, notifiche, recommendation…);
  • storage di oggetti (per file/media);
  • CDN (per asset e contenuti statici).

Walkthrough pratico

Per ogni use case chiave racconta il viaggio della richiesta:

  1. client → gateway/LB
  2. routing verso API server
  3. lettura/scrittura su cache e DB
  4. eventuali eventi asincroni
  5. risposta al client

Se introduci cache, parla esplicitamente di:

  • TTL
  • invalidation (write-through, cache-aside, ecc.)
  • rischio di dati stantii e mitigazioni

E quando opportuno, esplicita i trade-off legati a consistency/availability/partition tolerance (CAP): componenti diverse possono fare scelte diverse.


4) Bottleneck, scalabilità e affidabilità: cosa si rompe per primo?

È una fase breve ma ad altissimo segnale. Mostra che non stai progettando solo “happy path”.

Checklist utile:

  • Single points of failure: dove sei fragile? (DB singolo, cache non replicata, un solo AZ)
  • Ridondanza: multi-AZ, repliche, autoscaling
  • Fallback: percorsi degradati ma funzionanti (es. leggere da DB se cache down)
  • Throttling e rate limit per proteggere i downstream
  • Osservabilità: metriche, log, tracing, alert
    • latenza API (p95/p99)
    • error rate
    • saturazione risorse
    • code backlog (se asincrono)

Anche qui: check-in rapido su quali failure scenario approfondire evita di investire tempo su un’area che non è prioritaria.


5) Wrap-up: trade-off e possibili estensioni

Chiudi da “ingegnere”:

  • ricapitola 2–3 decisioni chiave (es. storage scelto, strategia cache, asincrono dove serve);
  • dichiara cosa hai prioritizzato (latenza? costo? disponibilità? consistenza?);
  • menziona 1–2 estensioni che implementeresti con più tempo (senza aprire nuovi buchi).

Questo dimostra consapevolezza: in system design si vince esplicitando cosa stai sacrificando e perché.


Sintesi operativa

Un buon system design non è un poster di microservizi: è un ragionamento guidato da requisiti, trade-off e gestione del tempo.

  • Parti chiarendo scope e vincoli.
  • Rendilo concreto con data model e API.
  • Disegna l’architettura raccontando i flussi.
  • Porta l’attenzione su bottleneck e failure mode.
  • Chiudi con trade-off ed estensioni.

Se applichi questo schema in modo coerente, anche un problema volutamente vago diventa gestibile: e soprattutto diventa valutabile nel modo giusto—sul tuo metodo, non sulla memoria di una “soluzione perfetta” che in produzione non esiste.