1{2 "_comment": "Dyno type -> EKS pod sizing + node selection. Used by the design EKS branch when design_constraints.compute_target.value is eks-managed or eks-or-ecs. DIRECT LOOKUP: read req_cpu/req_mem/lim_cpu/lim_mem + node_type per dyno. This file holds DATA only (pod rows, node-rank, cluster constants); the node-group SIZING ALGORITHM lives in design-eks.md prose.",3 "_match": "exact, case-insensitive, on formation config.dyno_type",4 "_on_not_found": "reject the formation; produce NO entry; warn 'Unsupported dyno type: {dyno_type}. Cannot map to EKS.'; continue (same as the Fargate path)",5 "rows": {6 "eco": {7 "req_cpu": "250m",8 "req_mem": "512Mi"
13 "_note": "Heroku Eco is a shared $5/month 1000 dyno-hour pool and Eco dynos sleep when idle; EKS pods run always-on, so the cost SHAPE changes even though the size matches. See the Eco dyno rule in references/shared/heroku-pricing-cache.md."
14 },
15 "basic": {
16 "req_cpu": "250m",
17 "req_mem": "512Mi",
18 "lim_cpu": "500m",
19 "lim_mem": "512Mi",
20 "node_type": "m6i.large",
21 "node_type_arm64": "m6g.large",
22 "_note": "Basic dynos never sleep, so this is a like-for-like always-on mapping."
23 },
24 "standard-1x": {
25 "req_cpu": "250m",
26 "req_mem": "512Mi",
27 "lim_cpu": "500m",
28 "lim_mem": "512Mi",
29 "node_type": "m6i.large",
30 "node_type_arm64": "m6g.large"
31 },
32 "standard-2x": {
33 "req_cpu": "500m",
34 "req_mem": "1024Mi",
35 "lim_cpu": "1000m",
36 "lim_mem": "1024Mi",
37 "node_type": "m6i.large",
38 "node_type_arm64": "m6g.large"
39 },
40 "performance-m": {
41 "req_cpu": "1000m",
42 "req_mem": "2560Mi",
43 "lim_cpu": "2000m",
44 "lim_mem": "2560Mi",
45 "node_type": "m6i.xlarge",
46 "node_type_arm64": "m6g.xlarge"
47 },
48 "performance-l": {
49 "req_cpu": "4000m",
50 "req_mem": "14336Mi",
51 "lim_cpu": "8000m",
52 "lim_mem": "14336Mi",
53 "node_type": "m6i.4xlarge",
54 "node_type_arm64": "m6g.4xlarge"
55 },
56 "performance-l-ram": {
57 "req_cpu": "4000m",
58 "req_mem": "30720Mi",
59 "lim_cpu": "8000m",
60 "lim_mem": "30720Mi",
61 "node_type": "r6i.4xlarge",
62 "node_type_arm64": "r6g.4xlarge"
63 },
64 "performance-xl": {
65 "req_cpu": "8000m",
66 "req_mem": "63488Mi",
67 "lim_cpu": "16000m",
68 "lim_mem": "63488Mi",
69 "node_type": "m6i.8xlarge",
70 "node_type_arm64": "m6g.8xlarge"
71 },
72 "performance-2xl": {
73 "req_cpu": "16000m",
74 "req_mem": "129024Mi",
75 "lim_cpu": "32000m",
76 "lim_mem": "129024Mi",
77 "node_type": "m6i.16xlarge",
78 "node_type_arm64": "m6g.16xlarge"
79 },
80 "private-s": {
81 "req_cpu": "500m",
82 "req_mem": "1024Mi",
83 "lim_cpu": "1000m",
84 "lim_mem": "1024Mi",
85 "node_type": "m6i.large",
86 "node_type_arm64": "m6g.large"
87 },
88 "private-m": {
89 "req_cpu": "1000m",
90 "req_mem": "2560Mi",
91 "lim_cpu": "2000m",
92 "lim_mem": "2560Mi",
93 "node_type": "m6i.xlarge",
94 "node_type_arm64": "m6g.xlarge"
95 },
96 "private-l": {
97 "req_cpu": "4000m",
98 "req_mem": "14336Mi",
99 "lim_cpu": "8000m",
100 "lim_mem": "14336Mi",
101 "node_type": "m6i.4xlarge",
102 "node_type_arm64": "m6g.4xlarge"
103 },
104 "private-l-ram": {
105 "req_cpu": "4000m",
106 "req_mem": "30720Mi",
107 "lim_cpu": "8000m",
108 "lim_mem": "30720Mi",
109 "node_type": "r6i.4xlarge",
110 "node_type_arm64": "r6g.4xlarge"
111 },
112 "private-xl": {
113 "req_cpu": "8000m",
114 "req_mem": "63488Mi",
115 "lim_cpu": "16000m",
116 "lim_mem": "63488Mi",
117 "node_type": "m6i.8xlarge",
118 "node_type_arm64": "m6g.8xlarge"
119 },
120 "private-2xl": {
121 "req_cpu": "16000m",
122 "req_mem": "129024Mi",
123 "lim_cpu": "32000m",
124 "lim_mem": "129024Mi",
125 "node_type": "m6i.16xlarge",
126 "node_type_arm64": "m6g.16xlarge"
127 },
128 "shield-s": {
129 "req_cpu": "500m",
130 "req_mem": "1024Mi",
131 "lim_cpu": "1000m",
132 "lim_mem": "1024Mi",
133 "node_type": "m6i.large",
134 "node_type_arm64": "m6g.large"
135 },
136 "shield-m": {
137 "req_cpu": "1000m",
138 "req_mem": "2560Mi",
139 "lim_cpu": "2000m",
140 "lim_mem": "2560Mi",
141 "node_type": "m6i.xlarge",
142 "node_type_arm64": "m6g.xlarge"
143 },
144 "shield-l": {
145 "req_cpu": "4000m",
146 "req_mem": "14336Mi",
147 "lim_cpu": "8000m",
148 "lim_mem": "14336Mi",
149 "node_type": "m6i.4xlarge",
150 "node_type_arm64": "m6g.4xlarge"
151 },
152 "shield-l-ram": {
153 "req_cpu": "4000m",
154 "req_mem": "30720Mi",
155 "lim_cpu": "8000m",
156 "lim_mem": "30720Mi",
157 "node_type": "r6i.4xlarge",
158 "node_type_arm64": "r6g.4xlarge"
159 },
160 "shield-xl": {
161 "req_cpu": "8000m",
162 "req_mem": "63488Mi",
163 "lim_cpu": "16000m",
164 "lim_mem": "63488Mi",
165 "node_type": "m6i.8xlarge",
166 "node_type_arm64": "m6g.8xlarge"
167 },
168 "shield-2xl": {
169 "req_cpu": "16000m",
170 "req_mem": "129024Mi",
171 "lim_cpu": "32000m",
172 "lim_mem": "129024Mi",
173 "node_type": "m6i.16xlarge",
174 "node_type_arm64": "m6g.16xlarge"
175 }
176 },
177 "node_size_rank": {
178 "_comment": "Rank for the 'largest-pod-class-wins' node selection: pick the node_type of the largest dyno present across all formations. Higher rank = larger. Tie at rank 3 (m6i.4xlarge vs r6i.4xlarge): prefer m6i.4xlarge UNLESS a RAM-optimized dyno (*-l-ram) is the only dyno at that rank, in which case use r6i.4xlarge.",
179 "m6i.large": 1,
180 "m6i.xlarge": 2,
181 "m6i.4xlarge": 3,
182 "r6i.4xlarge": 3,
183 "m6i.8xlarge": 4,
184 "m6i.16xlarge": 5
185 },
186 "system_overhead_per_node": {
187 "cpu": "500m",
188 "memory": "512Mi"
189 },
190 "_node_capacity_note": "PROVENANCE / verification-only \u2014 NOT read at runtime. The node-group sizing algorithm (design-eks.md) selects instance type by node_size_rank and computes node count as ceil(total_pods / 4) with min_size=2; it does NOT bin-pack against these allocatable figures. This block records WHY each node_type was chosen and why '>=4 pods per node' holds, so the node_type recommendations, the system_overhead totals, and the /4 divisor can be re-derived if dyno classes or overhead change. Allocatable = total minus system_overhead_per_node. Migrated from the former design-refs/eks-mapping-table.md 'Node Capacity Validation' + 'System Overhead Per Node' tables.",
191 "_system_overhead_breakdown": {
192 "kubelet": {
193 "cpu": "~100m",
194 "memory": "256Mi"
195 },
196 "kube-proxy": {
197 "cpu": "~100m",
198 "memory": "128Mi"
199 },
200 "aws-vpc-cni": {
201 "cpu": "~10m per ENI",
202 "memory": "128Mi"
203 },
204 "daemonsets_total": {
205 "cpu": "~290m",
206 "memory": "-"
207 },
208 "total": {
209 "cpu": "500m",
210 "memory": "512Mi"
211 }
212 },
213 "_node_capacity": {
214 "m6i.large": {
215 "vcpu": 2,
216 "memory": "8192Mi",
217 "allocatable_cpu": "1500m",
218 "allocatable_memory": "7680Mi",
219 "fits_ge_4_pods_of": [
220 "eco",
221 "basic",
222 "standard-1x",
223 "standard-2x",
224 "private-s",
225 "shield-s"
226 ]
227 },
228 "m6i.xlarge": {
229 "vcpu": 4,
230 "memory": "16384Mi",
231 "allocatable_cpu": "3500m",
232 "allocatable_memory": "15872Mi",
233 "fits_ge_4_pods_of": [
234 "performance-m",
235 "private-m",
236 "shield-m"
237 ]
238 },
239 "m6i.4xlarge": {
240 "vcpu": 16,
241 "memory": "65536Mi",
242 "allocatable_cpu": "15500m",
243 "allocatable_memory": "65024Mi",
244 "fits_ge_4_pods_of": [
245 "performance-l",
246 "private-l",
247 "shield-l"
248 ]
249 },
250 "r6i.4xlarge": {
251 "vcpu": 16,
252 "memory": "131072Mi",
253 "allocatable_cpu": "15500m",
254 "allocatable_memory": "130560Mi",
255 "fits_ge_4_pods_of": [
256 "performance-l-ram",
257 "private-l-ram",
258 "shield-l-ram"
259 ]
260 },
261 "m6i.8xlarge": {
262 "vcpu": 32,
263 "memory": "131072Mi",
264 "allocatable_cpu": "31500m",
265 "allocatable_memory": "130560Mi",
266 "fits_ge_4_pods_of": [
267 "performance-xl",
268 "private-xl",
269 "shield-xl"
270 ]
271 },
272 "m6i.16xlarge": {
273 "vcpu": 64,
274 "memory": "262144Mi",
275 "allocatable_cpu": "63500m",
276 "allocatable_memory": "261632Mi",
277 "fits_ge_4_pods_of": [
278 "performance-2xl",
279 "private-2xl",
280 "shield-2xl"
281 ]
282 }
283 },
284 "cluster": {
285 "cluster_name": "heroku-migration-cluster",
286 "kubernetes_version_fallback": "1.31",
287 "_kubernetes_version_note": "FALLBACK only. The design-eks procedure should query the latest EKS-supported stable version at generation time (aws eks describe-addon-versions) and use this value only when the query is unavailable. Do NOT treat 1.31 as pinned.",
288 "node_group_type_by_pref": {
289 "eks-managed": "self-managed",
290 "eks-or-ecs": "managed"
291 },
292 "_node_group_note": "eks-managed -> self-managed node groups (full K8s control); eks-or-ecs -> managed node groups (less operational burden).",