update docs

This commit is contained in:
2026-05-11 20:13:11 -03:00
commit 2ffabb672e
40 changed files with 5869 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
digraph cold_warm_timeline {
rankdir=LR
bgcolor="#0a0e17"
fontname="Helvetica"
node [fontname="Helvetica" fontsize=11 style=filled color="#1e2a4a" fontcolor="#e8eaf0" shape=box]
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
label="Cold vs warm — what gets billed, what gets measured"
labelloc=t
fontsize=16
fontcolor="#0066ff"
subgraph cluster_cold {
label="INVOCATION 1 — cold (Init Duration shows in CloudWatch)"
style=dashed
color="#ff3d00"
fontcolor="#ff3d00"
c_dl [label="Download code\n~50200 ms\n(NOT billed)" fillcolor="#121829" fontcolor="#8892a8"]
c_init [label="Init phase\n~200800 ms typical\n(boto3/aioboto3 imports,\nclient build)\n(billed at full mem)" fillcolor="#1a1a3a" fontcolor="#ffc107"]
c_handler [label="Handler\n~5500 ms\n(billed)" fillcolor="#0d1a33"]
c_freeze [label="freeze" fillcolor="#121829" fontcolor="#8892a8"]
}
subgraph cluster_warm1 {
label="INVOCATION 2 — warm (no Init Duration logged)"
style=dashed
color="#00c853"
fontcolor="#00c853"
w_thaw [label="thaw\nmicroseconds\n(NOT billed)" fillcolor="#121829" fontcolor="#8892a8"]
w_handler [label="Handler\n~5500 ms\n(billed)" fillcolor="#0d1a33" fontcolor="#00c853"]
w_freeze [label="freeze" fillcolor="#121829" fontcolor="#8892a8"]
}
subgraph cluster_warm2 {
label="INVOCATION 3 — warm"
style=dashed
color="#00c853"
fontcolor="#00c853"
w2_thaw [label="thaw" fillcolor="#121829" fontcolor="#8892a8"]
w2_handler [label="Handler\n(billed)" fillcolor="#0d1a33" fontcolor="#00c853"]
}
notes [label="Init Duration is ONLY in cold-start logs.\nDuration is the handler portion only.\nBilled Duration rounds Duration up to 1 ms.\nWith Provisioned Concurrency, init runs ahead of time —\nyou pay for it in PC pricing, not per invocation." fillcolor="#0a0e17" color="#1e2a4a" shape=note fontcolor="#b4bccf" fontsize=10]
c_dl -> c_init -> c_handler -> c_freeze
c_freeze -> w_thaw [label="next event\n(< idle window)" color="#00c853"]
w_thaw -> w_handler -> w_freeze
w_freeze -> w2_thaw [color="#00c853"]
w2_thaw -> w2_handler
{rank=sink; notes}
}

View File

@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.2 (0)
-->
<!-- Title: cold_warm_timeline Pages: 1 -->
<svg width="1511pt" height="223pt"
viewBox="0.00 0.00 1511.00 223.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 219.38)">
<title>cold_warm_timeline</title>
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-219.38 1506.75,-219.38 1506.75,4 -4,4"/>
<text xml:space="preserve" text-anchor="middle" x="751.38" y="-196.18" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">Cold vs warm — what gets billed, what gets measured</text>
<g id="clust1" class="cluster">
<title>cluster_cold</title>
<polygon fill="#0a0e17" stroke="#ff3d00" stroke-dasharray="5,2" points="8,-8 8,-127 519.75,-127 519.75,-8 8,-8"/>
<text xml:space="preserve" text-anchor="middle" x="263.88" y="-107.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#ff3d00">INVOCATION 1 — cold (Init Duration shows in CloudWatch)</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_warm1</title>
<polygon fill="#0a0e17" stroke="#00c853" stroke-dasharray="5,2" points="611,-22 611,-114 1017,-114 1017,-22 611,-22"/>
<text xml:space="preserve" text-anchor="middle" x="814" y="-94.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#00c853">INVOCATION 2 — warm (no Init Duration logged)</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_warm2</title>
<polygon fill="#0a0e17" stroke="#00c853" stroke-dasharray="5,2" points="1038,-28 1038,-108 1494.75,-108 1494.75,-28 1038,-28"/>
<text xml:space="preserve" text-anchor="middle" x="1266.38" y="-88.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#00c853">INVOCATION 3 — warm</text>
</g>
<!-- c_dl -->
<g id="node1" class="node">
<title>c_dl</title>
<polygon fill="#121829" stroke="#1e2a4a" points="116,-78.25 16,-78.25 16,-29.75 116,-29.75 116,-78.25"/>
<text xml:space="preserve" text-anchor="middle" x="66" y="-63.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">Download code</text>
<text xml:space="preserve" text-anchor="middle" x="66" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">~50200 ms</text>
<text xml:space="preserve" text-anchor="middle" x="66" y="-36.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">(NOT billed)</text>
</g>
<!-- c_init -->
<g id="node2" class="node">
<title>c_init</title>
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="306.25,-91.75 153,-91.75 153,-16.25 306.25,-16.25 306.25,-91.75"/>
<text xml:space="preserve" text-anchor="middle" x="229.62" y="-77.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">Init phase</text>
<text xml:space="preserve" text-anchor="middle" x="229.62" y="-63.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">~200800 ms typical</text>
<text xml:space="preserve" text-anchor="middle" x="229.62" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">(boto3/aioboto3 imports,</text>
<text xml:space="preserve" text-anchor="middle" x="229.62" y="-36.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">client build)</text>
<text xml:space="preserve" text-anchor="middle" x="229.62" y="-23.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">(billed at full mem)</text>
</g>
<!-- c_dl&#45;&gt;c_init -->
<g id="edge1" class="edge">
<title>c_dl&#45;&gt;c_init</title>
<path fill="none" stroke="#4a5568" d="M116.37,-54C124.38,-54 132.87,-54 141.45,-54"/>
<polygon fill="#4a5568" stroke="#4a5568" points="141.25,-57.5 151.25,-54 141.25,-50.5 141.25,-57.5"/>
</g>
<!-- c_handler -->
<g id="node3" class="node">
<title>c_handler</title>
<polygon fill="#0d1a33" stroke="#1e2a4a" points="420.75,-78.25 343.25,-78.25 343.25,-29.75 420.75,-29.75 420.75,-78.25"/>
<text xml:space="preserve" text-anchor="middle" x="382" y="-63.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">Handler</text>
<text xml:space="preserve" text-anchor="middle" x="382" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">~5500 ms</text>
<text xml:space="preserve" text-anchor="middle" x="382" y="-36.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(billed)</text>
</g>
<!-- c_init&#45;&gt;c_handler -->
<g id="edge2" class="edge">
<title>c_init&#45;&gt;c_handler</title>
<path fill="none" stroke="#4a5568" d="M306.69,-54C315.11,-54 323.52,-54 331.48,-54"/>
<polygon fill="#4a5568" stroke="#4a5568" points="331.28,-57.5 341.28,-54 331.28,-50.5 331.28,-57.5"/>
</g>
<!-- c_freeze -->
<g id="node4" class="node">
<title>c_freeze</title>
<polygon fill="#121829" stroke="#1e2a4a" points="511.75,-72 457.75,-72 457.75,-36 511.75,-36 511.75,-72"/>
<text xml:space="preserve" text-anchor="middle" x="484.75" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">freeze</text>
</g>
<!-- c_handler&#45;&gt;c_freeze -->
<g id="edge3" class="edge">
<title>c_handler&#45;&gt;c_freeze</title>
<path fill="none" stroke="#4a5568" d="M421.09,-54C429.25,-54 437.87,-54 446.02,-54"/>
<polygon fill="#4a5568" stroke="#4a5568" points="446,-57.5 456,-54 446,-50.5 446,-57.5"/>
</g>
<!-- w_thaw -->
<g id="node5" class="node">
<title>w_thaw</title>
<polygon fill="#121829" stroke="#1e2a4a" points="756.62,-78.25 664.88,-78.25 664.88,-29.75 756.62,-29.75 756.62,-78.25"/>
<text xml:space="preserve" text-anchor="middle" x="710.75" y="-63.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">thaw</text>
<text xml:space="preserve" text-anchor="middle" x="710.75" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">microseconds</text>
<text xml:space="preserve" text-anchor="middle" x="710.75" y="-36.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">(NOT billed)</text>
</g>
<!-- c_freeze&#45;&gt;w_thaw -->
<g id="edge4" class="edge">
<title>c_freeze&#45;&gt;w_thaw</title>
<path fill="none" stroke="#00c853" d="M511.88,-54C546.28,-54 607.68,-54 652.99,-54"/>
<polygon fill="#00c853" stroke="#00c853" points="652.92,-57.5 662.92,-54 652.92,-50.5 652.92,-57.5"/>
<text xml:space="preserve" text-anchor="middle" x="565.38" y="-67.95" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">next event</text>
<text xml:space="preserve" text-anchor="middle" x="565.38" y="-56.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">(&lt; idle window)</text>
</g>
<!-- w_handler -->
<g id="node6" class="node">
<title>w_handler</title>
<polygon fill="#0d1a33" stroke="#1e2a4a" points="871.12,-78.25 793.62,-78.25 793.62,-29.75 871.12,-29.75 871.12,-78.25"/>
<text xml:space="preserve" text-anchor="middle" x="832.38" y="-63.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">Handler</text>
<text xml:space="preserve" text-anchor="middle" x="832.38" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">~5500 ms</text>
<text xml:space="preserve" text-anchor="middle" x="832.38" y="-36.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">(billed)</text>
</g>
<!-- w_thaw&#45;&gt;w_handler -->
<g id="edge5" class="edge">
<title>w_thaw&#45;&gt;w_handler</title>
<path fill="none" stroke="#4a5568" d="M756.98,-54C765.16,-54 773.73,-54 782.03,-54"/>
<polygon fill="#4a5568" stroke="#4a5568" points="781.99,-57.5 791.99,-54 781.99,-50.5 781.99,-57.5"/>
</g>
<!-- w_freeze -->
<g id="node7" class="node">
<title>w_freeze</title>
<polygon fill="#121829" stroke="#1e2a4a" points="962.12,-72 908.12,-72 908.12,-36 962.12,-36 962.12,-72"/>
<text xml:space="preserve" text-anchor="middle" x="935.12" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">freeze</text>
</g>
<!-- w_handler&#45;&gt;w_freeze -->
<g id="edge6" class="edge">
<title>w_handler&#45;&gt;w_freeze</title>
<path fill="none" stroke="#4a5568" d="M871.46,-54C879.63,-54 888.25,-54 896.39,-54"/>
<polygon fill="#4a5568" stroke="#4a5568" points="896.37,-57.5 906.37,-54 896.37,-50.5 896.37,-57.5"/>
</g>
<!-- w2_thaw -->
<g id="node8" class="node">
<title>w2_thaw</title>
<polygon fill="#121829" stroke="#1e2a4a" points="1100,-72 1046,-72 1046,-36 1100,-36 1100,-72"/>
<text xml:space="preserve" text-anchor="middle" x="1073" y="-50.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#8892a8">thaw</text>
</g>
<!-- w_freeze&#45;&gt;w2_thaw -->
<g id="edge7" class="edge">
<title>w_freeze&#45;&gt;w2_thaw</title>
<path fill="none" stroke="#00c853" d="M962.32,-54C982.81,-54 1011.57,-54 1034.5,-54"/>
<polygon fill="#00c853" stroke="#00c853" points="1034.37,-57.5 1044.37,-54 1034.37,-50.5 1034.37,-57.5"/>
</g>
<!-- w2_handler -->
<g id="node9" class="node">
<title>w2_handler</title>
<polygon fill="#0d1a33" stroke="#1e2a4a" points="1486.75,-72 1428,-72 1428,-36 1486.75,-36 1486.75,-72"/>
<text xml:space="preserve" text-anchor="middle" x="1457.38" y="-57.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">Handler</text>
<text xml:space="preserve" text-anchor="middle" x="1457.38" y="-43.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">(billed)</text>
</g>
<!-- w2_thaw&#45;&gt;w2_handler -->
<g id="edge8" class="edge">
<title>w2_thaw&#45;&gt;w2_handler</title>
<path fill="none" stroke="#4a5568" d="M1100.28,-54C1166,-54 1337.82,-54 1416.27,-54"/>
<polygon fill="#4a5568" stroke="#4a5568" points="1416.07,-57.5 1426.07,-54 1416.07,-50.5 1416.07,-57.5"/>
</g>
<!-- notes -->
<g id="node10" class="node">
<title>notes</title>
<polygon fill="#0a0e17" stroke="#1e2a4a" points="1404,-187.88 1118,-187.88 1118,-116.12 1410,-116.12 1410,-181.88 1404,-187.88"/>
<polyline fill="none" stroke="#1e2a4a" points="1404,-187.88 1404,-181.88"/>
<polyline fill="none" stroke="#1e2a4a" points="1410,-181.88 1404,-181.88"/>
<text xml:space="preserve" text-anchor="middle" x="1264" y="-174.38" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#b4bccf">Init Duration is ONLY in cold&#45;start logs.</text>
<text xml:space="preserve" text-anchor="middle" x="1264" y="-161.62" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#b4bccf">Duration is the handler portion only.</text>
<text xml:space="preserve" text-anchor="middle" x="1264" y="-148.88" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#b4bccf">Billed Duration rounds Duration up to 1 ms.</text>
<text xml:space="preserve" text-anchor="middle" x="1264" y="-136.12" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#b4bccf">With Provisioned Concurrency, init runs ahead of time —</text>
<text xml:space="preserve" text-anchor="middle" x="1264" y="-123.38" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#b4bccf">you pay for it in PC pricing, not per invocation.</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

58
docs/graphs/lifecycle.dot Normal file
View File

@@ -0,0 +1,58 @@
digraph lifecycle {
rankdir=TB
bgcolor="#0a0e17"
fontname="Helvetica"
node [fontname="Helvetica" fontsize=11 style=filled color="#1e2a4a" fontcolor="#e8eaf0"]
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
label="Lambda execution environment lifecycle"
labelloc=t
fontsize=16
fontcolor="#0066ff"
subgraph cluster_cold {
label="Cold start (first invocation on a fresh execution environment)"
style=dashed
color="#ff3d00"
fontcolor="#ff3d00"
download [label="1. Download code\nzip / container layers" fillcolor="#243056" shape=box]
bootstrap [label="2. Start runtime\nbootstrap (python3.x)" fillcolor="#243056" shape=box]
init [label="3. Init phase\nrun module-level code\nimport boto3 / aioboto3\nbuild clients\n(billed; capped at 10 s)" fillcolor="#1a1a3a" shape=box fontcolor="#ffc107"]
}
subgraph cluster_invoke {
label="Invocation"
style=dashed
color="#1e2a4a"
fontcolor="#8892a8"
handler [label="handler(event, context)\nyour code runs\n(billed)" fillcolor="#0d1a33" shape=box]
respond [label="return / raise" fillcolor="#121829" shape=box]
}
subgraph cluster_warm {
label="Warm reuse (subsequent invocations on the same environment)"
style=dashed
color="#00c853"
fontcolor="#00c853"
thaw [label="thaw\n(microseconds)" fillcolor="#1a3a1a" shape=box]
reuse [label="globals retained:\nclients, /tmp,\nin-memory caches" fillcolor="#1a3a1a" shape=note fontcolor="#00c853"]
}
freeze [label="freeze\nprocess paused\n(after handler returns)" fillcolor="#121829" shape=box]
shutdown [label="shutdown\nidle ~515 min →\nenv torn down\n/tmp gone" fillcolor="#121829" shape=box fontcolor="#ff3d00"]
download -> bootstrap
bootstrap -> init
init -> handler [label="event arrives" color="#0066ff"]
handler -> respond
respond -> freeze
freeze -> thaw [label="next event" color="#00c853"]
thaw -> handler [label="reuse env" color="#00c853"]
reuse -> handler [style=dotted color="#00c853"]
freeze -> shutdown [label="idle too long" style=dashed color="#ff3d00"]
}

159
docs/graphs/lifecycle.svg Normal file
View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.2 (0)
-->
<!-- Title: lifecycle Pages: 1 -->
<svg width="1215pt" height="546pt"
viewBox="0.00 0.00 1215.00 546.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 541.5)">
<title>lifecycle</title>
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-541.5 1211.25,-541.5 1211.25,4 -4,4"/>
<text xml:space="preserve" text-anchor="middle" x="603.62" y="-518.3" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">Lambda execution environment lifecycle</text>
<g id="clust1" class="cluster">
<title>cluster_cold</title>
<polygon fill="#0a0e17" stroke="#ff3d00" stroke-dasharray="5,2" points="8,-202.25 8,-502 518,-502 518,-202.25 8,-202.25"/>
<text xml:space="preserve" text-anchor="middle" x="263" y="-482.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#ff3d00">Cold start (first invocation on a fresh execution environment)</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_invoke</title>
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="855,-8 855,-173 1019,-173 1019,-8 855,-8"/>
<text xml:space="preserve" text-anchor="middle" x="937" y="-153.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Invocation</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_warm</title>
<polygon fill="#0a0e17" stroke="#00c853" stroke-dasharray="5,2" points="526,-215.75 526,-307.75 1061,-307.75 1061,-215.75 526,-215.75"/>
<text xml:space="preserve" text-anchor="middle" x="793.5" y="-288.55" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#00c853">Warm reuse (subsequent invocations on the same environment)</text>
</g>
<!-- download -->
<g id="node1" class="node">
<title>download</title>
<polygon fill="#243056" stroke="#1e2a4a" points="503.12,-466.5 370.88,-466.5 370.88,-430.5 503.12,-430.5 503.12,-466.5"/>
<text xml:space="preserve" text-anchor="middle" x="437" y="-451.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">1. Download code</text>
<text xml:space="preserve" text-anchor="middle" x="437" y="-438.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">zip / container layers</text>
</g>
<!-- bootstrap -->
<g id="node2" class="node">
<title>bootstrap</title>
<polygon fill="#243056" stroke="#1e2a4a" points="505.75,-387.25 368.25,-387.25 368.25,-351.25 505.75,-351.25 505.75,-387.25"/>
<text xml:space="preserve" text-anchor="middle" x="437" y="-372.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">2. Start runtime</text>
<text xml:space="preserve" text-anchor="middle" x="437" y="-358.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">bootstrap (python3.x)</text>
</g>
<!-- download&#45;&gt;bootstrap -->
<g id="edge1" class="edge">
<title>download&#45;&gt;bootstrap</title>
<path fill="none" stroke="#4a5568" d="M437,-430.36C437,-421.12 437,-409.48 437,-398.91"/>
<polygon fill="#4a5568" stroke="#4a5568" points="440.5,-399.13 437,-389.13 433.5,-399.13 440.5,-399.13"/>
</g>
<!-- init -->
<g id="node3" class="node">
<title>init</title>
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="510.25,-285.75 363.75,-285.75 363.75,-210.25 510.25,-210.25 510.25,-285.75"/>
<text xml:space="preserve" text-anchor="middle" x="437" y="-271.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">3. Init phase</text>
<text xml:space="preserve" text-anchor="middle" x="437" y="-257.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">run module&#45;level code</text>
<text xml:space="preserve" text-anchor="middle" x="437" y="-244.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">import boto3 / aioboto3</text>
<text xml:space="preserve" text-anchor="middle" x="437" y="-230.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">build clients</text>
<text xml:space="preserve" text-anchor="middle" x="437" y="-217.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">(billed; capped at 10 s)</text>
</g>
<!-- bootstrap&#45;&gt;init -->
<g id="edge2" class="edge">
<title>bootstrap&#45;&gt;init</title>
<path fill="none" stroke="#4a5568" d="M437,-350.91C437,-336.89 437,-316.46 437,-297.56"/>
<polygon fill="#4a5568" stroke="#4a5568" points="440.5,-297.57 437,-287.57 433.5,-297.57 440.5,-297.57"/>
</g>
<!-- handler -->
<g id="node4" class="node">
<title>handler</title>
<polygon fill="#0d1a33" stroke="#1e2a4a" points="1010.62,-137.5 863.38,-137.5 863.38,-89 1010.62,-89 1010.62,-137.5"/>
<text xml:space="preserve" text-anchor="middle" x="937" y="-123.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">handler(event, context)</text>
<text xml:space="preserve" text-anchor="middle" x="937" y="-109.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">your code runs</text>
<text xml:space="preserve" text-anchor="middle" x="937" y="-96.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(billed)</text>
</g>
<!-- init&#45;&gt;handler -->
<g id="edge3" class="edge">
<title>init&#45;&gt;handler</title>
<path fill="none" stroke="#0066ff" d="M503.5,-209.81C509.66,-207.04 515.88,-204.46 522,-202.25 632.54,-162.3 766.53,-137.96 851.78,-125.3"/>
<polygon fill="#0066ff" stroke="#0066ff" points="852.08,-128.79 861.47,-123.88 851.06,-121.86 852.08,-128.79"/>
<text xml:space="preserve" text-anchor="middle" x="605.96" y="-183.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">event arrives</text>
</g>
<!-- respond -->
<g id="node5" class="node">
<title>respond</title>
<polygon fill="#121829" stroke="#1e2a4a" points="996,-52 908,-52 908,-16 996,-16 996,-52"/>
<text xml:space="preserve" text-anchor="middle" x="952" y="-30.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">return / raise</text>
</g>
<!-- handler&#45;&gt;respond -->
<g id="edge4" class="edge">
<title>handler&#45;&gt;respond</title>
<path fill="none" stroke="#4a5568" d="M941.58,-88.65C943.13,-80.69 944.87,-71.72 946.48,-63.42"/>
<polygon fill="#4a5568" stroke="#4a5568" points="949.88,-64.29 948.35,-53.81 943.01,-62.96 949.88,-64.29"/>
</g>
<!-- freeze -->
<g id="node8" class="node">
<title>freeze</title>
<polygon fill="#121829" stroke="#1e2a4a" points="1193.88,-393.5 1054.12,-393.5 1054.12,-345 1193.88,-345 1193.88,-393.5"/>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-379.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">freeze</text>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-365.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">process paused</text>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-352.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(after handler returns)</text>
</g>
<!-- respond&#45;&gt;freeze -->
<g id="edge5" class="edge">
<title>respond&#45;&gt;freeze</title>
<path fill="none" stroke="#4a5568" d="M996.29,-51.39C1052.72,-74.98 1147.76,-124.41 1188,-202.25 1221.33,-266.72 1205.08,-295.28 1184,-327 1181.66,-330.52 1178.9,-333.83 1175.88,-336.92"/>
<polygon fill="#4a5568" stroke="#4a5568" points="1173.59,-334.27 1168.5,-343.56 1178.27,-339.48 1173.59,-334.27"/>
</g>
<!-- thaw -->
<g id="node6" class="node">
<title>thaw</title>
<polygon fill="#1a3a1a" stroke="#1e2a4a" points="1050.38,-266 949.62,-266 949.62,-230 1050.38,-230 1050.38,-266"/>
<text xml:space="preserve" text-anchor="middle" x="1000" y="-251.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">thaw</text>
<text xml:space="preserve" text-anchor="middle" x="1000" y="-237.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(microseconds)</text>
</g>
<!-- thaw&#45;&gt;handler -->
<g id="edge7" class="edge">
<title>thaw&#45;&gt;handler</title>
<path fill="none" stroke="#00c853" d="M991.76,-229.65C981.97,-209.01 965.41,-174.11 953.05,-148.08"/>
<polygon fill="#00c853" stroke="#00c853" points="956.31,-146.78 948.86,-139.25 949.99,-149.78 956.31,-146.78"/>
<text xml:space="preserve" text-anchor="middle" x="994.4" y="-183.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">reuse env</text>
</g>
<!-- reuse -->
<g id="node7" class="node">
<title>reuse</title>
<polygon fill="#1a3a1a" stroke="#1e2a4a" points="925.62,-272.25 814.38,-272.25 814.38,-223.75 931.62,-223.75 931.62,-266.25 925.62,-272.25"/>
<polyline fill="none" stroke="#1e2a4a" points="925.62,-272.25 925.62,-266.25"/>
<polyline fill="none" stroke="#1e2a4a" points="931.62,-266.25 925.62,-266.25"/>
<text xml:space="preserve" text-anchor="middle" x="873" y="-257.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">globals retained:</text>
<text xml:space="preserve" text-anchor="middle" x="873" y="-244.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">clients, /tmp,</text>
<text xml:space="preserve" text-anchor="middle" x="873" y="-230.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">in&#45;memory caches</text>
</g>
<!-- reuse&#45;&gt;handler -->
<g id="edge8" class="edge">
<title>reuse&#45;&gt;handler</title>
<path fill="none" stroke="#00c853" stroke-dasharray="1,5" d="M884.44,-223.27C894.54,-202.31 909.39,-171.53 920.72,-148.01"/>
<polygon fill="#00c853" stroke="#00c853" points="923.81,-149.67 925,-139.14 917.5,-146.63 923.81,-149.67"/>
</g>
<!-- freeze&#45;&gt;thaw -->
<g id="edge6" class="edge">
<title>freeze&#45;&gt;thaw</title>
<path fill="none" stroke="#00c853" d="M1092.05,-344.65C1085.01,-339.08 1077.73,-333 1071.25,-327 1053.59,-310.64 1035.31,-290.56 1021.69,-274.86"/>
<polygon fill="#00c853" stroke="#00c853" points="1024.4,-272.65 1015.23,-267.34 1019.09,-277.21 1024.4,-272.65"/>
<text xml:space="preserve" text-anchor="middle" x="1095.62" y="-318.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">next event</text>
</g>
<!-- shutdown -->
<g id="node9" class="node">
<title>shutdown</title>
<polygon fill="#121829" stroke="#1e2a4a" points="1179.25,-279 1068.75,-279 1068.75,-217 1179.25,-217 1179.25,-279"/>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-264.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ff3d00">shutdown</text>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-251.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ff3d00">idle ~515 min →</text>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-237.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ff3d00">env torn down</text>
<text xml:space="preserve" text-anchor="middle" x="1124" y="-224.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ff3d00">/tmp gone</text>
</g>
<!-- freeze&#45;&gt;shutdown -->
<g id="edge9" class="edge">
<title>freeze&#45;&gt;shutdown</title>
<path fill="none" stroke="#ff3d00" stroke-dasharray="5,2" d="M1124,-344.69C1124,-329.32 1124,-308.83 1124,-290.76"/>
<polygon fill="#ff3d00" stroke="#ff3d00" points="1127.5,-290.82 1124,-280.82 1120.5,-290.82 1127.5,-290.82"/>
<text xml:space="preserve" text-anchor="middle" x="1151.75" y="-318.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">idle too long</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,70 @@
digraph system_overview {
rankdir=LR
bgcolor="#0a0e17"
fontname="Helvetica"
node [fontname="Helvetica" fontsize=11 style=filled color="#1e2a4a" fontcolor="#e8eaf0"]
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
label="Sample app — Lambda + MinIO sandbox"
labelloc=t
fontsize=16
fontcolor="#0066ff"
subgraph cluster_caller {
label="Caller"
style=dashed
color="#1e2a4a"
fontcolor="#8892a8"
invoke [label="invoke.py\n(local) /\nAPI Gateway,\nS3 event,\nStep Functions\n(real AWS)" fillcolor="#243056" shape=box]
}
subgraph cluster_lambda {
label="Lambda execution environment"
style=dashed
color="#0066ff"
fontcolor="#0066ff"
handler [label="handler(event, context)\nlambda_function.py" fillcolor="#1a1a3a" shape=box]
subgraph cluster_async {
label="asyncio.Queue producer / consumer"
style=dotted
color="#0066ff"
fontcolor="#8892a8"
producer [label="producer\nlist_objects_v2 (paginator)\nfilter *.pdf" fillcolor="#0d1a33" shape=box]
queue [label="asyncio.Queue\nmaxsize=2000\n(backpressure)" fillcolor="#121829" shape=cylinder]
consumer [label="consumer\ngenerate_presigned_url\nappend JSONL" fillcolor="#0d1a33" shape=box]
}
tmp [label="/tmp/<uuid>.jsonl\nstreamed manifest\n(ephemeral, 512 MB default)" fillcolor="#121829" shape=cylinder fontcolor="#ffc107"]
}
subgraph cluster_storage {
label="Object storage"
style=dashed
color="#1e2a4a"
fontcolor="#8892a8"
minio [label="MinIO (local)\nor real S3" fillcolor="#1a3a1a" shape=cylinder fontcolor="#00c853"]
bucket [label="my-company-reports-bucket\n2026/04/*.pdf\nmanifests/<uuid>.jsonl" fillcolor="#121829" shape=folder]
}
response [label="response\n{count, manifest_key,\nmanifest_url}\n(< 1 KB; sidesteps 6 MB cap)" fillcolor="#243056" shape=note fontcolor="#00c853"]
invoke -> handler [label="event"]
handler -> producer [label="spawn task"]
handler -> consumer [label="spawn task"]
producer -> minio [label="LIST"]
minio -> producer [label="page (1000 keys)" style=dashed]
producer -> queue [label="key" color="#0066ff"]
queue -> consumer [label="key"]
consumer -> minio [label="presign\n(local HMAC)" style=dotted]
consumer -> tmp [label="JSONL line"]
tmp -> minio [label="put_object\nmanifests/<uuid>.jsonl"]
handler -> response [label="return"]
minio -> bucket [style=invis]
}

View File

@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.2 (0)
-->
<!-- Title: system_overview Pages: 1 -->
<svg width="1531pt" height="306pt"
viewBox="0.00 0.00 1531.00 306.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 301.5)">
<title>system_overview</title>
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-301.5 1526.75,-301.5 1526.75,4 -4,4"/>
<text xml:space="preserve" text-anchor="middle" x="761.38" y="-278.3" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">Sample app — Lambda + MinIO sandbox</text>
<g id="clust1" class="cluster">
<title>cluster_caller</title>
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="8,-95 8,-228 121,-228 121,-95 8,-95"/>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-208.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Caller</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_lambda</title>
<polygon fill="#0a0e17" stroke="#0066ff" stroke-dasharray="5,2" points="166.5,-108 166.5,-262 1308,-262 1308,-108 166.5,-108"/>
<text xml:space="preserve" text-anchor="middle" x="737.25" y="-242.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">Lambda execution environment</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_async</title>
<polygon fill="#0a0e17" stroke="#0066ff" stroke-dasharray="1,5" points="409,-116 409,-226 1040.75,-226 1040.75,-116 409,-116"/>
<text xml:space="preserve" text-anchor="middle" x="724.88" y="-206.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">asyncio.Queue producer / consumer</text>
</g>
<g id="clust4" class="cluster">
<title>cluster_storage</title>
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="1162,-8 1162,-100 1514.75,-100 1514.75,-8 1162,-8"/>
<text xml:space="preserve" text-anchor="middle" x="1338.38" y="-80.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Object storage</text>
</g>
<!-- invoke -->
<g id="node1" class="node">
<title>invoke</title>
<polygon fill="#243056" stroke="#1e2a4a" points="113,-192.5 16,-192.5 16,-103.5 113,-103.5 113,-192.5"/>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-178.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">invoke.py</text>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-164.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(local) /</text>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-151.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">API Gateway,</text>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-137.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">S3 event,</text>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-124.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">Step Functions</text>
<text xml:space="preserve" text-anchor="middle" x="64.5" y="-110.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(real AWS)</text>
</g>
<!-- handler -->
<g id="node2" class="node">
<title>handler</title>
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="321.75,-166 174.5,-166 174.5,-130 321.75,-130 321.75,-166"/>
<text xml:space="preserve" text-anchor="middle" x="248.12" y="-151.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">handler(event, context)</text>
<text xml:space="preserve" text-anchor="middle" x="248.12" y="-137.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">lambda_function.py</text>
</g>
<!-- invoke&#45;&gt;handler -->
<g id="edge1" class="edge">
<title>invoke&#45;&gt;handler</title>
<path fill="none" stroke="#4a5568" d="M113.22,-148C128.48,-148 145.85,-148 162.92,-148"/>
<polygon fill="#4a5568" stroke="#4a5568" points="162.54,-151.5 172.54,-148 162.54,-144.5 162.54,-151.5"/>
<text xml:space="preserve" text-anchor="middle" x="143.75" y="-150.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">event</text>
</g>
<!-- producer -->
<g id="node3" class="node">
<title>producer</title>
<polygon fill="#0d1a33" stroke="#1e2a4a" points="578.5,-172.25 417,-172.25 417,-123.75 578.5,-123.75 578.5,-172.25"/>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-157.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">producer</text>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-144.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">list_objects_v2 (paginator)</text>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-130.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">filter *.pdf</text>
</g>
<!-- handler&#45;&gt;producer -->
<g id="edge2" class="edge">
<title>handler&#45;&gt;producer</title>
<path fill="none" stroke="#4a5568" d="M322.08,-148C348.16,-148 377.89,-148 405.33,-148"/>
<polygon fill="#4a5568" stroke="#4a5568" points="405.01,-151.5 415.01,-148 405.01,-144.5 405.01,-151.5"/>
<text xml:space="preserve" text-anchor="middle" x="365.25" y="-150.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">spawn task</text>
</g>
<!-- consumer -->
<g id="node5" class="node">
<title>consumer</title>
<polygon fill="#0d1a33" stroke="#1e2a4a" points="1032.75,-181.25 888.5,-181.25 888.5,-132.75 1032.75,-132.75 1032.75,-181.25"/>
<text xml:space="preserve" text-anchor="middle" x="960.62" y="-166.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">consumer</text>
<text xml:space="preserve" text-anchor="middle" x="960.62" y="-153.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">generate_presigned_url</text>
<text xml:space="preserve" text-anchor="middle" x="960.62" y="-139.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">append JSONL</text>
</g>
<!-- handler&#45;&gt;consumer -->
<g id="edge3" class="edge">
<title>handler&#45;&gt;consumer</title>
<path fill="none" stroke="#4a5568" d="M321.87,-165.21C349,-171.06 380.15,-177.09 408.75,-181 569.01,-202.91 611.48,-216.8 772.25,-199 807.08,-195.14 844.9,-187.37 877.38,-179.55"/>
<polygon fill="#4a5568" stroke="#4a5568" points="877.83,-183.05 886.71,-177.27 876.16,-176.25 877.83,-183.05"/>
<text xml:space="preserve" text-anchor="middle" x="630.25" y="-209.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">spawn task</text>
</g>
<!-- response -->
<g id="node9" class="node">
<title>response</title>
<polygon fill="#243056" stroke="#1e2a4a" points="580.75,-100 408.75,-100 408.75,-38 586.75,-38 586.75,-94 580.75,-100"/>
<polyline fill="none" stroke="#1e2a4a" points="580.75,-100 580.75,-94"/>
<polyline fill="none" stroke="#1e2a4a" points="586.75,-94 580.75,-94"/>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-85.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">response</text>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-72.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">{count, manifest_key,</text>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-58.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">manifest_url}</text>
<text xml:space="preserve" text-anchor="middle" x="497.75" y="-45.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">(&lt; 1 KB; sidesteps 6 MB cap)</text>
</g>
<!-- handler&#45;&gt;response -->
<g id="edge11" class="edge">
<title>handler&#45;&gt;response</title>
<path fill="none" stroke="#4a5568" d="M306.87,-129.58C333.84,-120.97 366.73,-110.48 397.51,-100.66"/>
<polygon fill="#4a5568" stroke="#4a5568" points="398.4,-104.05 406.86,-97.68 396.27,-97.38 398.4,-104.05"/>
<text xml:space="preserve" text-anchor="middle" x="365.25" y="-120.6" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">return</text>
</g>
<!-- queue -->
<g id="node4" class="node">
<title>queue</title>
<path fill="#121829" stroke="#1e2a4a" d="M772.25,-184.28C772.25,-187.63 750.18,-190.34 723,-190.34 695.82,-190.34 673.75,-187.63 673.75,-184.28 673.75,-184.28 673.75,-129.72 673.75,-129.72 673.75,-126.37 695.82,-123.66 723,-123.66 750.18,-123.66 772.25,-126.37 772.25,-129.72 772.25,-129.72 772.25,-184.28 772.25,-184.28"/>
<path fill="none" stroke="#1e2a4a" d="M772.25,-184.28C772.25,-180.94 750.18,-178.22 723,-178.22 695.82,-178.22 673.75,-180.94 673.75,-184.28"/>
<text xml:space="preserve" text-anchor="middle" x="723" y="-166.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">asyncio.Queue</text>
<text xml:space="preserve" text-anchor="middle" x="723" y="-153.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">maxsize=2000</text>
<text xml:space="preserve" text-anchor="middle" x="723" y="-139.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(backpressure)</text>
</g>
<!-- producer&#45;&gt;queue -->
<g id="edge6" class="edge">
<title>producer&#45;&gt;queue</title>
<path fill="none" stroke="#0066ff" d="M578.66,-148.22C603.39,-148.6 630.71,-149.35 655.75,-150.75 657.91,-150.87 660.11,-151.01 662.34,-151.16"/>
<polygon fill="#0066ff" stroke="#0066ff" points="661.8,-154.63 672.04,-151.88 662.33,-147.65 661.8,-154.63"/>
<text xml:space="preserve" text-anchor="middle" x="630.25" y="-153.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">key</text>
</g>
<!-- minio -->
<g id="node7" class="node">
<title>minio</title>
<path fill="#1a3a1a" stroke="#1e2a4a" d="M1255.75,-59.69C1255.75,-62.1 1236.53,-64.06 1212.88,-64.06 1189.22,-64.06 1170,-62.1 1170,-59.69 1170,-59.69 1170,-20.31 1170,-20.31 1170,-17.9 1189.22,-15.94 1212.88,-15.94 1236.53,-15.94 1255.75,-17.9 1255.75,-20.31 1255.75,-20.31 1255.75,-59.69 1255.75,-59.69"/>
<path fill="none" stroke="#1e2a4a" d="M1255.75,-59.69C1255.75,-57.27 1236.53,-55.31 1212.88,-55.31 1189.22,-55.31 1170,-57.27 1170,-59.69"/>
<text xml:space="preserve" text-anchor="middle" x="1212.88" y="-43.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">MinIO (local)</text>
<text xml:space="preserve" text-anchor="middle" x="1212.88" y="-29.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">or real S3</text>
</g>
<!-- producer&#45;&gt;minio -->
<g id="edge4" class="edge">
<title>producer&#45;&gt;minio</title>
<path fill="none" stroke="#4a5568" d="M578.76,-132.08C608.53,-126.37 642.63,-120.1 673.75,-115 721.03,-107.25 1032.17,-64.57 1158.6,-47.28"/>
<polygon fill="#4a5568" stroke="#4a5568" points="1158.95,-50.76 1168.39,-45.94 1158.01,-43.83 1158.95,-50.76"/>
<text xml:space="preserve" text-anchor="middle" x="830.38" y="-100.82" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">LIST</text>
</g>
<!-- queue&#45;&gt;consumer -->
<g id="edge7" class="edge">
<title>queue&#45;&gt;consumer</title>
<path fill="none" stroke="#4a5568" d="M772.48,-155.98C778.47,-155.89 784.5,-155.8 790.25,-155.75 825.92,-155.41 834.83,-155.5 870.5,-155.75 872.56,-155.76 874.64,-155.78 876.74,-155.8"/>
<polygon fill="#4a5568" stroke="#4a5568" points="876.57,-159.3 886.6,-155.89 876.64,-152.3 876.57,-159.3"/>
<text xml:space="preserve" text-anchor="middle" x="830.38" y="-158.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">key</text>
</g>
<!-- tmp -->
<g id="node6" class="node">
<title>tmp</title>
<path fill="#121829" stroke="#1e2a4a" d="M1300,-180.28C1300,-183.63 1260.95,-186.34 1212.88,-186.34 1164.8,-186.34 1125.75,-183.63 1125.75,-180.28 1125.75,-180.28 1125.75,-125.72 1125.75,-125.72 1125.75,-122.37 1164.8,-119.66 1212.88,-119.66 1260.95,-119.66 1300,-122.37 1300,-125.72 1300,-125.72 1300,-180.28 1300,-180.28"/>
<path fill="none" stroke="#1e2a4a" d="M1300,-180.28C1300,-176.94 1260.95,-174.22 1212.88,-174.22 1164.8,-174.22 1125.75,-176.94 1125.75,-180.28"/>
<text xml:space="preserve" text-anchor="middle" x="1212.88" y="-162.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">/tmp/&lt;uuid&gt;.jsonl</text>
<text xml:space="preserve" text-anchor="middle" x="1212.88" y="-149.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">streamed manifest</text>
<text xml:space="preserve" text-anchor="middle" x="1212.88" y="-135.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">(ephemeral, 512 MB default)</text>
</g>
<!-- consumer&#45;&gt;tmp -->
<g id="edge9" class="edge">
<title>consumer&#45;&gt;tmp</title>
<path fill="none" stroke="#4a5568" d="M1033,-155.86C1058.16,-155.46 1086.89,-155 1113.86,-154.57"/>
<polygon fill="#4a5568" stroke="#4a5568" points="1113.84,-158.07 1123.78,-154.41 1113.73,-151.07 1113.84,-158.07"/>
<text xml:space="preserve" text-anchor="middle" x="1079.25" y="-158.18" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">JSONL line</text>
</g>
<!-- consumer&#45;&gt;minio -->
<g id="edge8" class="edge">
<title>consumer&#45;&gt;minio</title>
<path fill="none" stroke="#4a5568" stroke-dasharray="1,5" d="M992.03,-132.46C1008.5,-120.4 1029.72,-106.73 1050.75,-98.5 1074.67,-89.14 1083.23,-96.65 1107.75,-89 1125.6,-83.43 1144.31,-75.39 1160.87,-67.42"/>
<polygon fill="#4a5568" stroke="#4a5568" points="1162.09,-70.72 1169.52,-63.16 1159,-64.44 1162.09,-70.72"/>
<text xml:space="preserve" text-anchor="middle" x="1079.25" y="-112.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">presign</text>
<text xml:space="preserve" text-anchor="middle" x="1079.25" y="-101.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">(local HMAC)</text>
</g>
<!-- tmp&#45;&gt;minio -->
<g id="edge10" class="edge">
<title>tmp&#45;&gt;minio</title>
<path fill="none" stroke="#4a5568" d="M1212.88,-119.53C1212.88,-105.74 1212.88,-89.75 1212.88,-75.73"/>
<polygon fill="#4a5568" stroke="#4a5568" points="1216.38,-76.03 1212.88,-66.03 1209.38,-76.03 1216.38,-76.03"/>
<text xml:space="preserve" text-anchor="middle" x="1198.62" y="-94.56" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">put_object</text>
<text xml:space="preserve" text-anchor="middle" x="1198.62" y="-83.31" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">manifests/&lt;uuid&gt;.jsonl</text>
</g>
<!-- minio&#45;&gt;producer -->
<g id="edge5" class="edge">
<title>minio&#45;&gt;producer</title>
<path fill="none" stroke="#4a5568" stroke-dasharray="5,2" d="M1169.68,-40.78C1093.42,-42.74 927.8,-49.54 790.25,-72.75 738.1,-81.55 725.32,-85.28 673.75,-97 642.95,-104 635.14,-105.39 604.75,-114 598.1,-115.88 591.24,-117.9 584.35,-119.99"/>
<polygon fill="#4a5568" stroke="#4a5568" points="583.53,-116.58 574.99,-122.86 585.58,-123.27 583.53,-116.58"/>
<text xml:space="preserve" text-anchor="middle" x="830.38" y="-75.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">page (1000 keys)</text>
</g>
<!-- bucket -->
<g id="node8" class="node">
<title>bucket</title>
<polygon fill="#121829" stroke="#1e2a4a" points="1506.75,-64.25 1503.75,-68.25 1482.75,-68.25 1479.75,-64.25 1337,-64.25 1337,-15.75 1506.75,-15.75 1506.75,-64.25"/>
<text xml:space="preserve" text-anchor="middle" x="1421.88" y="-49.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">my&#45;company&#45;reports&#45;bucket</text>
<text xml:space="preserve" text-anchor="middle" x="1421.88" y="-36.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">2026/04/*.pdf</text>
<text xml:space="preserve" text-anchor="middle" x="1421.88" y="-22.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">manifests/&lt;uuid&gt;.jsonl</text>
</g>
<!-- minio&#45;&gt;bucket -->
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB