Low Level Design: Template Engine

Template Syntax

Core syntax: {{variable}} for variable substitution, {{#if condition}}...{{/if}} for conditionals, {{#each items}}...{{/each}} for loops, {{> partial_name}} for partials, and {{block name}}...{{/block}} for template inheritance blocks.

Data Model

Template (
  id          SERIAL PRIMARY KEY,
  name        VARCHAR NOT NULL,
  version     INT NOT NULL,
  source      TEXT NOT NULL,
  compiled_bytecode BYTEA,
  created_at  TIMESTAMP DEFAULT NOW()
)

Compilation Pipeline

Parse source into an AST, then generate bytecode or target-language code (e.g., Python) from the AST, and store the compiled form in compiled_bytecode. On rendering, load the compiled template and execute it with the provided context dict, avoiding re-parse overhead.

Template Inheritance

A base template defines named blocks via {{block name}}...{{/block}}. A child template declares {{extends base_template}} and overrides individual blocks. Blocks not overridden fall back to the base definition. Partials are reusable sub-templates included via {{> partial_name}}.

Context Sandboxing

Restrict attribute access to an explicit whitelist. Prevent access to dangerous attributes such as __class__, __globals__, __subclasses__. Evaluate expressions in a restricted environment — no built-in eval, no file I/O, no subprocess execution. Jinja2 SandboxedEnvironment is a reference implementation.

Caching

Compiled templates are cached in Redis keyed by name:version. LRU eviction policy limits memory usage. On template update, the version is incremented and the old Redis key is deleted to invalidate the cache. Hot reload is automatic: next render fetches and re-caches the new compiled version.

Multi-Tenancy

Templates are scoped by tenant_id. Lookup resolves tenant-specific override first, then falls back to the default (global) template. This allows tenants to customize templates without forking the base.

Rendering Metrics

Track render time per template name using a histogram (e.g., Prometheus). Alert on p99 render latency exceeding threshold. Metrics help identify slow templates caused by complex loops or excessive partial inclusion.

See also: Atlassian Interview Guide

See also: Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence

See also: Shopify Interview Guide

Scroll to Top