Skip to content
FlowScript templates

Engineering — C4 container view of an ML scoring platform

C4 container view of a real-time ML scoring platform: the systems that call it, the serving and training services, the shared feature and model services, and the stores each owns — where an architecture review starts. Typed FlowScript for software architecture. Keywords: C4, container, system context, architecture.

Template previewFlowScript
Real-time fraud-scoring platformC4 — container view · ML platform teamCheckout service[external system]Mobile banking app[external system]SYSTEM BOUNDARYEDGEBACKENDCOREDATAAPI gateway[Container: Envoy; mTLS, rate limits]EDGEScoring service[Container: Triton; p99 under 40 ms]BACKENDTraining pipeline[Container: Spark on Kubernetes]BACKENDFeature service[Container: Go; online and offline]COREModel registry[Container: MLflow; staged promotion]COREFeature store[Datastore: redis + parquet]DATAModel artefacts[Datastore: s3]DATACheckout service → API gatewayMobile banking app → API gateway

Make it your own.

// C4 container view of a real-time ML scoring platform: the systems that call it, the serving and training services, the shared feature and model services, and the stores each owns — where an architecture review starts.
//
// Every string below is EXAMPLE text from a fictional system: replace it.
//
// C4 level 2: each box is a separately deployable unit (a service or a
// data store), not a class or a module. Edges are declared on the CALLER:
// depends: [x] reads "this container calls x", so the direction of every
// arrow is a statement someone can check against the network policy.
// Every store is owned by exactly one service; a store two services write
// to is a coupling worth naming in review.
//
// The design point the diagram makes: training and online scoring read
// features through the SAME feature service (point-in-time snapshots for
// training, the online store for serving) and meet again at the model
// registry. That shared path is what keeps training–serving skew out; a
// training job that read raw tables directly would show up here as an
// arrow that bypasses the feature service.
//
// Rows follow the tier attribute: edge (internet-facing), backend (the
// two workloads), core (shared platform services), then data stores.

system ml_platform {
  title: "Real-time fraud-scoring platform"
  owner: "ML platform team"
}

actor checkout {
  title: "Checkout service"
  kind: "external system"
  depends: [gateway]
}
actor mobile_app {
  title: "Mobile banking app"
  kind: "external system"
  depends: [gateway]
}

service gateway {
  title: "API gateway"
  runtime: "Envoy; mTLS, rate limits"
  depends: [scoring]
  tier: "edge"
}
service scoring {
  title: "Scoring service"
  runtime: "Triton; p99 under 40 ms"
  depends: [feature_service, registry]
  tier: "backend"
}
service training {
  title: "Training pipeline"
  runtime: "Spark on Kubernetes"
  depends: [registry, feature_service]
  tier: "backend"
}
service feature_service {
  title: "Feature service"
  runtime: "Go; online and offline"
  depends: [feature_store]
  tier: "core"
}
service registry {
  title: "Model registry"
  runtime: "MLflow; staged promotion"
  depends: [artefacts]
  tier: "core"
}

datastore feature_store {
  kind: "redis + parquet"
  title: "Feature store"
}
datastore artefacts {
  kind: "s3"
  title: "Model artefacts"
}

view containers: c4_container(ml_platform)