Skip to content
Connect an agent
Other diagram kinds

Layered architecture

A layered diagram stacks the tiers of a system, one wide layer for each, with the blocks that live in each layer and the few links that show how the layers call each other. It is the picture that opens almost every design document: presentation, application, data, infrastructure. It is for anyone, human or AI agent, who writes diagram source.

TL;DR

QuestionAnswer
What is it for?The shape of a system by tier: which blocks sit in which layer, and which layer calls which. Use a flow diagram when the picture is about how a request moves, and layers when it is about where things live.
How do I start one?Write layers "Title", then layer "Name" { blocks with block id "Label" lines inside, and } to close each layer. Write a link between two blocks as web -> api : "REST".
What is drawn?Each layer is a wide frame with a corner tab and a quiet wash of its tone. Each block is a tinted card with an icon, a label, and a note. Links run in the gaps between the rows and never cross a block.
Which way does it stack?The first layer is on top. direction=up puts it at the bottom instead, for a stack built on its foundation.
What cuts across every layer?An aside: a tall band beside the stack, such as security or monitoring, with its own blocks. It takes no links, because it applies to every layer.
How wide is a block?A layer divides its width into equal columns, and a block is one column wide. span=2 makes a block as wide as two, so a database can be wider than a service.
What are the limits?12 layers, 2 asides, 80 blocks, and 80 links. Past one, the source is refused with E140. More than 8 blocks in a layer, or more than 20 links, draws a warning.
Does Mermaid convert?Not yet. Mermaid block-beta is a grid of blocks with no layers. See From Mermaid.

Ask your agent

text
Use Plotwork to draw a layered diagram of our online banking platform. Four layers: Experience (web app, mobile app, API gateway), Domain services (accounts, payments, ledger), Data (PostgreSQL, Redis, Kafka) and Infrastructure (Kubernetes, the private network). Put security and monitoring in an aside beside the layers, and show the calls between the layers with their protocols.
text
Use Plotwork to draw a three-tier web app: a browser and a CDN, a REST API with an auth service and background jobs, and a database and an object store. Show which blocks call which, and label each call.

Example

Online banking platform: 4 layers, 14 blocks, 1 aside, 6 links. A customer reaches accounts, payments and cards through one gateway. Each layer calls the layer below it, and security and monitoring cut across all of them.

The four tones carry meaning: blue is what customers touch, violet is the business logic, aqua is where data lives, and neutral is the platform underneath. The PostgreSQL block has span=2, so it is as wide as two columns of the Data layer. The dotted line is an asynchronous call, the dashed line is a looser link, and the line with two heads is a two-way call. The aside stands beside the stack and is as tall as it, because security and monitoring touch every layer.

Three-tier web app

The oldest layered picture. counts=on shows how many blocks each layer holds, and the call from the CDN to the object store skips the application layer, so it runs down the lane on the right of the stack instead of through a block.

Three-tier web app: 3 layers, 7 blocks, 5 links. A browser talks to a web tier, the web tier calls an application tier, and only the application tier reaches the database.

Hexagonal ports and adapters

The domain depends on nothing, the application owns the ports, and the adapters on both sides plug into them. Three dashed links leave the Ports block, skip the Domain layer, and take a lane each.

Hexagonal architecture: 4 layers, 11 blocks, 8 links. Driving adapters call the application through ports, and the application reaches the outside world through driven adapters. The domain depends on nothing.

A cloud platform on AWS

Provider icons work as they do in a flow diagram: find them with the search_icons tool or in the icon reference. A vendor's own icon is drawn unmodified on its own tile in place of the chip. The link from API Gateway to Lambda joins two blocks of one row, so it runs under the row, inside the layer.

Serverless platform on AWS: 3 layers, 11 blocks, 1 aside, 5 links. Requests enter at the edge, run in functions, and land in managed data stores. Operations cut across every layer.

Microservices, from the foundation up

With direction=up the first layer written is the foundation, at the bottom, so the picture reads from the stores up to the clients. Seven services do not fit one row at a readable width, so the layer wraps to two rows and the last row is centred. A link from a block in the upper row goes along the gap between the rows to the lane, so write the blocks that have links in the row nearest the layer they link to.

Microservices: 4 layers, 16 blocks, 10 links. Clients reach services through a gateway, and each service owns its store. The first layer written is the foundation, at the bottom.

The language

One statement to a line. Text is always in double quotes, options are key=value, and # starts a comment. Indentation is for the reader and means nothing to the parser: nesting comes from the braces.

StatementMeaningExample
layers "Title" direction=<down|up> counts=<on|off> desc="<text>"The header. Every option is optional, and so is the title.layers "Online banking" direction=down
desc "<text>"The plain-language description, as a statement. The same as desc= on the header.desc "Each layer calls the layer below it."
layer "<Name>" tone=<tone> icon=<icon> {Opens a layer. Write blocks inside it, and close it with } on its own line.layer "Domain" tone=violet icon=lucide:boxes {
block <id> "<Label>" sub="<note>" icon=<icon> tone=<tone> span=<1-6>A card in the layer or aside that is open.block pay "Payments" sub="Go" icon=lucide:credit-card span=2
aside "<Name>" tone=<tone> icon=<icon> {Opens a band on the right of the stack, with its own blocks stacked in it.aside "Security" icon=lucide:shield {
<from> -> <to> : "<label>"A link between two blocks of the layers. The label is optional.web -> pay : "REST"
}Closes the layer or aside that is open, on a line of its own.}

A block's id is the word a link names. It starts with a letter, may contain letters, digits, _ and -, and is unique in the diagram. A link may be written before the blocks it joins.

Plotwork
layers "Shop"
layer "App" {  block web "Storefront" icon=lucide:globe  block api "API" sub="Checkout and catalog" icon=lucide:server}
layer "Data" {  block db "Database" icon=lucide:database}
web -> api : "HTTPS"api -> db : "SQL"

Layers and tone

A layer takes the next tone of a rotation (blue, violet, aqua, orange, amber, neutral) unless tone= sets one, and its blocks keep the tone. A block may choose its own, to mark one block out. Choose tones for meaning, as the example does, and nobody writes a color value: the theme owns every color in light and dark. Green and red are left out of the rotation because they read as good and bad news; choose them with tone= when they should mean that.

Blocks, columns, and spans

A layer divides its width into equal columns and puts one block in each, 12px apart. When the blocks fit one row with every word whole, they fill it, so a layer of three blocks has three wide cards. When they do not, the blocks wrap to the fewest rows, as even as the order allows, and a short last row is centred so its cards keep the width of the rows above. What a card holds, the icon and the text, is centred in it, so the room at its left and its right is the same.

span=2 makes a block as wide as two columns, and the other blocks keep their one. A span can be at most 6, and never more columns than the layer has.

Asides

An aside is a tall band beside the stack for what cuts across every layer: security, monitoring, delivery. It has a dashed edge, which says it cuts across, its own corner tab, and its blocks hang from the tab one under the other. It stands on the right of the stack, as wide as its widest block or its name needs, and as tall as the stack; if its blocks need more height than the layers, the layers grow to match. Two asides stand side by side. A block in an aside takes no links, and a link to one is an error that says why.

Links leave and enter the top and bottom of a block, so a line is never squeezed into the gap between two cards. Between layers that are next to each other a link runs along the gap between them. A link between two blocks of one row runs under the row, inside the layer. A link that skips a layer runs along the gap to a lane on the right of the stack, down the lane, and back along the gap above its target. Every line stays out of every block, and a link between blocks that stand over each other is straight.

ArrowLineHeadsSay it for
->solidone, at the second blockA call or a flow of data.
-->dashedoneA reply, a read, or a link that is optional or indirect.
<->solidtwoA two-way call.
<-->dashedtwoA two-way link that is optional or indirect.
..>dottedoneAn asynchronous call: an event, a webhook.
--solidnoneAn association with no direction.

Keep the few links that show how the layers depend on each other. A layered picture with forty links is a flow diagram that wants to be one.

Direction and counts

direction=up puts the first layer at the bottom, for a stack built on its foundation, and everything else reads the same. counts=on shows how many blocks each layer and aside holds, in a pill in its tab.

Limits and warnings

LimitValueWhat happens past it
Layers12E140 before any layout, with the advice to merge layers.
Asides2E140.
Blocks, in the layers and asides together80E140.
Links80E140.
A span6E136.
Blocks in a layer before the density warning8W200.
Links before the density warning20W200.

The picture is 880px wide, the width a Markdown column keeps text readable at, and grows taller with the rows and with the room the links need. The layout is plain arithmetic, so 80 blocks and 80 links are laid out in a few milliseconds.

A block is as wide as its column, and its label wraps to at most three lines, so a word is kept whole by giving its layer fewer, wider columns. Text is cut with an ellipsis, and W203 says so, only when no column could hold the word. The full text is always in the text description of the picture.

Every mistake comes back as a result with a code, a line, a column, and a hint. Warnings never stop the drawing.

CodeWhen it firesFix
E100A line that does not start with a keyword or a block id, a layer or an aside with no name or no block, a block outside any layer, a layer inside another, a link from a block to itself, text after a statement, or a diagram with no layers.Read the hint, which names the line to write.
E101, E110, E121, E122, E123An unterminated string, an unknown statement, an unknown tone, an unknown icon, or an unknown direction.Read the hint, which names the nearest choice.
E130, E131A block id used twice, or a link to a block that does not exist or is in an aside.Pick another id, or declare the block, or link a block of a layer.
E133, E134A layer or an aside that is never closed, or a } with nothing to close.Add or remove the brace.
E135, E136An unknown option, or a bad value for counts= or span=.Read the hint, which says what to write.
E140More than 12 layers, 2 asides, 80 blocks, or 80 links.Merge layers, fold blocks, or split the diagram.
W200A layer with no blocks, a layer with more than 8 blocks, or more than 20 links.Fill or remove the layer, split a crowded layer in two, or keep the links that matter.
W202The picture is wider than a Markdown column and its text would shrink.Shorten the labels.
W203A block label, a tab name, or a link label was cut with an ellipsis.Shorten it, or move detail into sub=.

From Mermaid

Mermaid block-beta is not read yet. It draws a grid of blocks with no layers and no meaning for a layer, so no mapping from it to a layered picture is right, and the converter reports it as a type it does not draw. Two things work today. Describe the system to your agent, or paste the Mermaid and say which blocks are tiers, and ask it to draw the layers; that is a better picture than a converted grid. If the Mermaid is a flowchart with subgraph blocks for the tiers, it converts to a flow diagram with a group for each tier, which keeps the arrows between the boxes. The migration guide covers the converter in full.

text
Use Plotwork to draw this Mermaid block diagram as a layered architecture. Make each row a layer, name the layers from what is in them, and keep the arrows as links between blocks.

See also

DocWhy
Writing diagramsThe flow, sequence and schema languages, and the rules every kind shares
Examples to copyFinished diagrams with the prompt that gets an agent to write each one
Architecture patternsChecked cloud and network patterns an agent can fill in, when the picture is how traffic flows
Cloud architectureAccounts, regions and networks as nested groups, when the picture is where things run
Migrating from MermaidConvert existing Mermaid diagrams, and what is dropped
Language referenceEvery kind, node type, option and diagnostic
Diagram kindsThe kinds Plotwork draws and the header of each