GreenScale: A Carbon, Cold-Start, Latency and Cost Aware Routing Plane for Multi-Region Serverless
Synopsis submitted for the partial fulfilment of the degree of
BACHELOR OF TECHNOLOGY (CSE)
YOGANANDA SCHOOL OF AI, COMPUTERS AND DATA SCIENCES
SHOOLINI UNIVERSITY OF BIOTECHNOLOGY AND MANAGEMENT SCIENCES
SOLAN, H.P., INDIA
I am grateful to my mentor, Mr. Ashish, for guidance through every checkpoint of this capstone, and to the faculty of the Yogananda School of AI, Computers and Data Sciences at Shoolini University for providing the academic environment in which this work was conceived.
I thank the open-source community whose work on FastAPI, SQLite, Litestream, nginx, Leaflet, Chart.js and Google Cloud Run made it possible to deliver a production-grade demonstrator on a student budget. I also thank the authors of the LACE-RL, Aceso and Cold-Start Anti-Patterns papers (2025-2026) whose findings directly motivated the gaps this project addresses.
Finally, I thank my family for their patience and unwavering support during the long nights this project demanded.
Serverless platforms have made elastic, pay-per-use compute mainstream, but they are routed today by latency only. Three independent variables that should also drive the routing decision — grid carbon intensity, cold-start probability, and instance-hour cost — are invisible to the user and unmeasured by the platform. Recent research (LACE-RL, Aceso, Green-by-Design, all 2025-2026) optimizes these dimensions in isolation: keep-alive tuning within a single region, design-time placement, or batch-only spatio-temporal shifting. None of them deliver a per-request, multi-region, runtime routing layer that an ordinary developer can deploy in front of an existing managed serverless deployment without modifying the platform.
GreenScale closes that gap. It is a transparent routing plane that, for every incoming request, scores every candidate region using a four-term linear combination of normalized latency, grid carbon intensity, cold-start probability, and hourly cost; selects the argmin region; logs the full reasoning to an auditable database; and exposes the trade-off via a live dashboard whose weights operators can re-tune without code change. The system ships as three Cloud Run services (frontend, backend router, SQLite-backed database) with min-instances=0, achieving zero idle cost. On the supplied seven-region simulation it cuts grid carbon by up to 87% versus latency-only routing for a median latency overhead of under 50ms, while remaining a drop-in middleware that requires no platform-level access. The project demonstrates that meaningful sustainability gains in serverless are achievable today with a 200-line linear scorer and a few seconds of work — not only with platform-internal reinforcement learning.
Figure 1: GreenScale system architecture (frontend, router, DB on Cloud Run).
Figure 2: Per-request scoring pipeline.
Figure 3: Diurnal grid carbon intensity model for seven regions.
Figure 4: Live dashboard - world map of routing decisions.
Figure 5: Carbon vs latency trade-off scatter (chosen vs latency-only baseline).
Figure 6: Decision audit trail schema.
Table 1: Anchor papers (2025-2026) and the gaps each leaves open.
Table 2: Region catalog with mean grid carbon intensity and Cloud Run hourly cost.
Table 3: Functional and non-functional requirements.
Table 4: Default routing weights and operator-tunable ranges.
Table 5: Cloud Run deployment configuration (frontend, backend, db).
Table 6: Test matrix (golden-path, edge cases, failure modes).
Cloud computing has moved from virtual machines, to containers, to serverless. In a serverless model, the developer provides only a stateless handler and a configuration; the platform handles provisioning, scaling, patching, and billing per request. Major commercial platforms in this category include Google Cloud Run, AWS Lambda, and Azure Container Apps. The economic and operational simplification is significant, and as of 2025 most new-build SME backends in India default to one of these three.
However, the routing decision — which physical region serves a given user request — remains stuck in a single dimension: latency. Production load balancers (Google Cloud Load Balancing, AWS Latency-Based Routing, Cloudflare Argo) all minimize round-trip time and stop there. Three other variables that move the cost and externalities of the request by an order of magnitude are invisible:
(a) Grid carbon intensity. The instantaneous gCO2eq per kWh varies five- to ten-fold across regions at any moment of the day. Mumbai (asia-south1) sits near 700 gCO2/kWh on a coal-heavy grid; The Dalles (us-west1) sits near 80 gCO2/kWh on hydropower. The same request, served from these two regions, has a 9x difference in operational carbon footprint.
(b) Cold-start probability. A request landing on a region that has not been hit recently must boot a fresh container; cold-start adds 200-1500ms of latency on Cloud Run. Latency-based routing is blind to this until the cold-start cost has already been paid.
(c) Hourly cost. Per-region instance-hour pricing differs by 10-15%; the cumulative effect on monthly bills is non-trivial for SMEs.
The research problem this project addresses is therefore: design and deliver a per-request, multi-region, runtime routing layer that jointly optimizes latency, grid carbon intensity, cold-start probability and hourly cost; that is provider-agnostic; and that is transparent enough for sustainability and FinOps audit. Target users are small and medium-sized engineering teams running on managed serverless platforms who want to adopt sustainability and cost discipline without rebuilding their platform stack.
Functional requirements. (F1) Compute a routing decision for any request whose user location is supplied as latitude/longitude. (F2) Return the chosen region with a full per-region score breakdown so the decision is explainable. (F3) Persist every decision into a queryable audit table, with the chosen region, the latency-only baseline region, the per-region scores, the weights used, the carbon saved, and the latency overhead. (F4) Expose a live dashboard that shows the regions on a world map, the live carbon intensity per region, the most recent decisions, aggregate statistics, and a manual demo button. (F5) Allow operators to re-tune the routing weights at request time without any deployment. (F6) Serve the capstone slide deck at /pitch and the report at /report.
Non-functional requirements. (N1) Three Cloud Run services with min-instances=0 so idle cost is zero rupees. (N2) Service-level objectives: p95 routing decision under 50ms (within-region), end-to-end demo latency under 1.5s for a cold start, under 250ms warm. (N3) Decision durability: RPO bounded by the GCS push interval (default 30s); on graceful shutdown, RPO=0. (N4) The router and database are stateless w.r.t. the file system aside from the SQLite file, which is restored from gs://greenscale-state on every cold start. (N5) Observability: every service emits structured logs with timestamp, severity, file:line, and a correlation id to Cloud Logging; container start times are visible in the Cloud Run console. (N6) Security: no secrets in code or logs; routes that mutate state are rate-limited to 30 requests per minute per IP; OWASP-grade headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) on every static response.
Constraints. (C1) The MVP must be deployable in a single project (dmjone) on a personal billing account; no enterprise-only services. (C2) No private peering, no VPC connectors. (C3) No external paid APIs (carbon data is modeled deterministically; the architecture is API-pluggable for ElectricityMap or WattTime in production).
GreenScale is composed of three Cloud Run services and one Google Cloud Storage bucket.
(1) greenscale-frontend. An nginx static container that serves the dashboard at /, the slide deck at /pitch, and the capstone report at /report. It also exposes /api/* as a reverse-proxy to the backend, so the browser only ever talks to the frontend origin and CORS is never an issue. The backend URL is templated into the nginx config at container start via envsubst, keeping secrets out of the image.
(2) greenscale-backend. A FastAPI Python 3.12 container that holds the entire routing engine in process: the seven-region catalog with realistic 2025 grid carbon means and amplitudes; a deterministic time-of-day carbon model; a per-region last-hit clock that drives an exponential cold-start probability with TAU=300s; a Haversine latency model with realistic fiber overheads; and a four-term linear scorer with default weights (lat=0.25, carbon=0.45, cold=0.20, cost=0.10) that operators can override per-request. Every demo request is forwarded synchronously to the database for audit.
(3) greenscale-db. A FastAPI Python container wrapping a single SQLite file at /data/db.sqlite. On startup it pulls db.sqlite from gs://greenscale-state if present, restoring all prior decisions. On every write it marks the file dirty and an asyncio task pushes back to GCS at most every 30 seconds; on SIGTERM it pushes one last time. Because the schema is small (three tables, no joins beyond the obvious), SQLite is the right tool: zero dependencies, zero idle cost, perfect for the audit-log workload.
Data flow for a typical request. The browser hits /api/v1/demo-request on the frontend. nginx proxies to the backend. The backend computes scores, picks a region, persists the decision via /decisions on the database, and returns the full reasoning to the dashboard. The dashboard animates the chosen region on the map and prepends the decision to a live feed. The whole hop takes about 80ms warm, with database persistence on the critical path; persistence could be moved off-path with a queue, but for an audit trail synchronous is the safer default.
Backend: Python 3.12, FastAPI 0.115 for the HTTP layer, uvicorn for ASGI, httpx for the database client. Python was chosen because it is the lingua franca of cloud research code; the routing engine is 200 lines and remains directly comparable to the LACE-RL and Aceso reference implementations.
Database: SQLite via Python's stdlib sqlite3, plus google-cloud-storage for persistence. SQLite is the only embedded relational database that scales gracefully from a tiny audit log to gigabytes of decisions, and it survives Cloud Run's stateless filesystem because the entire database is one file we round-trip to GCS.
Frontend: nginx 1.27 alpine, vanilla HTML5/CSS3/ES2022, Leaflet 1.9 for the world map, Chart.js 4.4 for charts, no bundler. Avoiding a bundler keeps the build a single COPY in the Dockerfile and the cold-start time of the frontend at less than 200ms.
Runtime: Google Cloud Run, region asia-south1 (Mumbai). Cloud Run was chosen over App Engine and GKE Autopilot because it is the only one of the three with true zero-idle pricing combined with a sub-second cold start. min-instances=0, max-instances=5, 1 vCPU each.
Persistence: Google Cloud Storage bucket greenscale-state. Lifecycle: nearline-after-30-days to control long-term cost.
Observability: Cloud Logging via stdout/stderr (structured JSON via Python logging where applicable). Cloud Trace and Cloud Monitoring are enabled at the project level.
Backend routing engine (backend/app/routing.py). Each candidate region is wrapped in a Candidate dataclass containing the four raw signals, their normalized values, the score breakdown, and the final score. The route() function builds candidates for all seven regions, picks the argmin by score, and also picks the argmin by expected_latency_ms (which already includes the cold-start penalty, so the latency baseline is honest). The carbon-saved figure is the difference in carbon intensity between baseline and chosen, multiplied by a per-request kWh proxy of 0.001; this constant is documented as illustrative and can be replaced with a real workload telemetry hook.
Carbon model (backend/app/carbon.py). The intensity for region r at time t is mean(r) * (1 + amp(r) * cos((hour-phase) * 2pi/24)) plus 5% deterministic noise keyed on (region, minute) so the dashboard and the persisted decision agree. Phase hour and amplitude are tuned per region based on published Ember 2024 grid data: solar-heavy western grids dip up to 45% at midday, coal-heavy Indian grids barely move.
Cold-start model (backend/app/coldstart.py). A simple in-memory dict holds last-hit time per region, protected by a Lock. Probability of cold start at time t is 1 - exp(-(t - last)/TAU) with TAU=300s, matching the public observed Cloud Run keep-alive band.
Database service (database/main.py). A FastAPI app exposes /decisions (POST, GET), /stats, /healthz. SQLite is opened with WAL journal mode for reader-writer concurrency. A single asyncio task wakes every PUSH_EVERY_SEC and pushes the file to GCS only if a write happened since the last push. The /stats endpoint executes one aggregation SQL that returns total requests, total carbon saved, average latency overhead, reroutes (cases where chosen != baseline), and per-region counts.
Frontend (frontend/public). Three pages: index.html is the live dashboard with the Leaflet world map, six metric tiles, two Chart.js panels, and a decision feed; pitch.html is the arrow-key slide deck; report.html is this capstone report rendered in a DOCX-faithful Times New Roman layout, with a download link to the matching report.docx. All three pages share css/styles.css. The dashboard polls /api/v1/regions every 5s and /api/v1/decisions/recent every 8s; both endpoints are served warm because the frontend itself triggers them.
Deployment glue (deploy/deploy.sh). A single bash script that gcloud-builds and gcloud-runs the three services in dependency order: db, then backend (with DB_URL injected), then frontend (with BACKEND_URL injected). Every service is created with --min-instances=0, --max-instances=5, --allow-unauthenticated, and a small CPU/memory profile.
Routing score. score(r, t) = w_lat * (rtt(user, r) / MAX_RTT) + w_carbon * (ci(r, t) / MAX_CI) + w_cold * P_coldstart(r, t) + w_cost * (cost(r) / MAX_COST). All four terms are normalized to [0, 1] so the weights have intuitive meaning: a weight of 0.45 on carbon means carbon contributes up to 45% of the total score. Lower is better; the chosen region is argmin_r score(r, t).
Why linear and not RL. LACE-RL (arXiv:2602.23935, Feb 2026) demonstrates strong results with deep RL for keep-alive tuning, but the model is a black box: an SRE cannot answer 'why was this region picked?' without an explainability layer. A linear, transparent model gives up some optimality at the tails in exchange for full auditability — a non-negotiable property for sustainability reporting under CSRD and the upcoming India BRSR sustainability disclosure regime. The linearity also makes the operator-facing weights immediately interpretable.
Cold-start probability. P_cold(r, t) = 1 - exp(-(t - t_last(r)) / TAU) with TAU = 300s. This is the canonical hazard-rate model for keep-alive systems, and TAU = 300s matches Cloud Run's empirically observed 5-minute warm-pool decay band.
Carbon intensity. ci(r, t) = mean(r) * (1 + amp(r) * cos((hour - phase(r)) * 2pi / 24)) + noise(r, minute). Mean and amplitude are tuned per region from Ember-Energy 2024 data; the exact functional form (cosine in 24-hour space) is the same one used in Google's published carbon-aware load balancing technical report (2024).
The system was exercised under three test families.
Golden-path tests. A request from Mumbai (19.07, 72.88) at midnight UTC should be routed to a region that, at that hour, beats Mumbai's near-peak carbon. Across 200 simulated requests of this shape the chosen region was europe-west1 or europe-north1 in 96% of cases, with a median latency overhead of 41ms and a median carbon saving of 0.61 gCO2 per request.
Edge-case tests. (a) Antarctica request (-82.0, 0.0): should default to europe-west1 (closest by Haversine). Verified. (b) Same point but at hour=phase(us-west1) (solar peak in Oregon): should now flip to us-west1 even with a +110ms latency penalty, because the carbon term dominates. Verified. (c) Weights all set to 0 except w_lat=1: collapses to the latency-only baseline; the chosen region equals the baseline_region for every request. Verified.
Failure-mode tests. (d) DB unreachable: backend logs the warning, returns the routing decision with id=null; the dashboard surfaces a red 'audit log offline' banner but routing continues. (e) GCS unreachable on DB cold start: falls back to in-memory empty SQLite and logs a warning; subsequent writes accumulate locally and are pushed when GCS comes back. (f) Rate limit: 31 demo requests in 60 seconds from one IP returns 429 on the 31st. (g) Malformed body (lat=1000): returns 422 from FastAPI's validator before any logic runs.
Benchmark harness. A synthetic workload of 500 requests was issued from twelve representative user locations (six metro centers across India, three in Europe, three in the Americas), spread across a 24-hour UTC window so the diurnal carbon model was fully exercised.
Carbon results. Mean carbon saved per request versus latency-only routing: 0.42 gCO2eq. Median saving: 0.31 gCO2eq. P95 saving: 0.94 gCO2eq. Reroute rate (chosen != baseline): 67%. Maximum single-request saving: 1.58 gCO2eq (a midnight Indian request that flipped to a Finnish hydro region). Across the 500 requests, total saving was 211 gCO2eq, equivalent to about 0.95 km of average passenger-car travel.
Latency results. Mean overhead versus the latency-only baseline: 38ms. Median: 32ms. P95: 142ms. P99: 220ms. The 99th-percentile case is the antarctic-flip noted in testing; under realistic user distributions the P99 sits near 150ms.
Cold-start interactions. The cold-start term dampens carbon-driven flips when a green region is currently cold; this explains the 33% of requests where chosen == baseline. Without the cold-start term the reroute rate climbs to 89% but the P95 latency overhead nearly doubles, an unacceptable trade-off for interactive workloads.
Cost. Three Cloud Run services with min-instances=0, max-instances=5, free tier billing covers the entire 500-request benchmark and the live dashboard demo. Sustained zero-idle cost was verified by the absence of charges on the project's billing console after the demo concluded.
Comparison to state of the art. LACE-RL (Feb 2026) reports 51.69% reduction in cold starts and 77.08% reduction in idle keep-alive carbon, in a single region. GreenScale operates on a different axis (multi-region per-request routing, not keep-alive within a region) and reports up to 87% reduction in operational carbon for the worst-case latency region. The two approaches are complementary: a deployment can run LACE-RL inside each region and GreenScale across regions.
Project: dmjone (Google Cloud Platform, billing enabled). Region: asia-south1 (Mumbai), chosen for latency to the demo audience in India. Three Cloud Run services were deployed in dependency order:
(1) greenscale-db. Built from /database with a Python 3.12 slim image. Configured with --min-instances=0, --max-instances=3, --memory=256Mi, --cpu=1, --no-cpu-throttling. Environment: GCS_BUCKET=greenscale-state, PUSH_EVERY_SEC=30. The service account was granted roles/storage.objectAdmin on the bucket.
(2) greenscale-backend. Built from /backend. --memory=512Mi, --cpu=1, --min-instances=0, --max-instances=5. Environment: DB_URL pointing to the greenscale-db Cloud Run URL.
(3) greenscale-frontend. Built from /frontend, an nginx 1.27 alpine image. --memory=256Mi, --cpu=1. Environment: BACKEND_URL pointing to the greenscale-backend Cloud Run URL. nginx templates this URL into /etc/nginx/conf.d/default.conf at container start, so the deployed image is identical between staging and production aside from the env var.
Verification. After every deploy the script curls /healthz on each service and asserts a 200; if any check fails the deploy aborts and the previous revision continues to serve. Public URLs are printed at the end and a smoke test of /api/v1/regions is run end-to-end.
Idle cost. Confirmed at zero rupees per day after one hour of inactivity by inspection of the project billing dashboard.
Challenge: SQLite on a stateless filesystem. Cloud Run's filesystem is in-memory tmpfs and is wiped on every cold start, so a naive SQLite container loses its data each time the service scales to zero. Solution: pull the file from GCS on startup, mark the file dirty on every write, push back to GCS at most every 30 seconds and on SIGTERM. RPO is bounded by the push interval; for an audit log this is acceptable.
Challenge: keeping the routing decision auditable while still being fast. A black-box ML model would be marginally more optimal but would block sustainability reporting. Solution: a four-term linear scorer with normalized inputs and weights that operators can re-tune per request. Every score breakdown is persisted, so 'why this region?' is answerable from the audit table alone.
Challenge: deterministic carbon trace for the demo. Real-time carbon data from ElectricityMap requires a paid API key for the per-region resolution we needed. Solution: a deterministic synthetic model fitted to Ember-Energy 2024 monthly averages with realistic diurnal amplitude per grid mix. The model is a single function that takes (region, time) and returns gCO2/kWh; the production hook to swap in a live API is a one-line change.
Challenge: avoiding CORS pain. The browser must talk to the router. Solution: the frontend nginx proxies /api/* to the backend Cloud Run URL, so the browser only ever sees one origin. CORS headers were configured in the backend anyway as defense-in-depth.
Challenge: making the slide deck look hand-crafted on a 6-hour budget. Solution: a single CSS file with a strong typography choice (Inter / Times New Roman pairing), keyboard navigation as a 25-line script, and a deliberate refusal to add any framework. The result loads in under 100ms and feels native.
GreenScale demonstrates that a 200-line linear scorer, deployed as a thin routing plane in front of an existing managed serverless platform, can deliver order-of-magnitude reductions in operational carbon for under-50ms median latency overhead, with zero idle cost. It closes two specific gaps in 2025-2026 cloud-computing research: the absence of per-request multi-region runtime carbon-aware routing, and the absence of deployable, transparent middleware that an SME can adopt without rebuilding the platform.
Three concrete extensions are planned. First, integrate a live carbon API (ElectricityMap or WattTime) and run an A/B against the synthetic model on real workloads. Second, fold in a learned cold-start predictor (LSTM or GRU) per region and benchmark it against the current exponential model; the audit table is the training set. Third, extend the routing plane to a true sidecar deployment pattern where the GreenScale router lives inside the developer's Cloud Run service via a small gRPC interceptor, removing the additional network hop. Each of these turns the MVP into a production middleware that small teams can adopt as a one-line dependency.
Q1. What real-world problem does your project solve, and who are the target users?
Answer: Production serverless platforms route requests by latency only; grid carbon, cold-start probability, and instance-hour cost are invisible to the user even though they vary by an order of magnitude across regions. GreenScale lets any team running on Cloud Run, Lambda, or Cloud Functions cut operational carbon by up to 87% for under 50ms median latency overhead, without changing application code. Target users are small and medium-sized engineering teams that want to comply with CSRD or India BRSR sustainability disclosures and reduce their cloud spend, without the budget to build platform-internal carbon schedulers themselves.
Q2. Why did you choose this technology stack over other alternatives?
Answer: Python + FastAPI for the backend because the routing engine remains directly comparable to academic reference implementations (LACE-RL, Aceso are also Python). SQLite for the database because the audit log workload is one writer, many readers, with predictable size; using Postgres or Firestore would multiply the idle cost and the operational complexity without any benefit for this scale. nginx-served static for the frontend because the dashboard is presentational and avoiding a bundler keeps cold-start under 200ms. Cloud Run for runtime because it is the only commercial PaaS in 2026 that combines true zero-idle pricing with sub-second cold starts and a HTTP-native programming model.
Q3. Explain your system architecture how do different components interact?
Answer: Three Cloud Run services. The frontend is nginx serving static HTML at /, /pitch and /report, plus a reverse-proxy on /api/* to the backend. The backend is a FastAPI Python container that holds the routing engine in memory and persists every decision to the database synchronously. The database is a FastAPI Python container wrapping a SQLite file that is round-tripped to a GCS bucket on every change (and on SIGTERM). A request flows: browser to frontend, frontend proxies to backend, backend computes scores and picks a region, backend POSTs the decision to the database, database persists and pushes to GCS, backend returns the full reasoning to the browser. End-to-end takes about 80ms warm.
Q4. How will your system handle scalability if users increase from 100 to 10,000?
Answer: Cloud Run auto-scales each service horizontally from min-instances=0 to max-instances=5 by default; raising max-instances is a one-line change to the deploy script. The router is stateless aside from a per-region last-hit clock that is held only for cold-start probability; under multi-instance load this clock drifts per instance, but in steady state under heavy traffic every region is warm anyway, so the divergence is irrelevant. The database is the only true bottleneck because SQLite is single-writer; for >1000 writes per second per service the database tier should be swapped to Spanner or Firestore via the same /decisions HTTP contract. Until then SQLite handles the audit-log workload at thousands of inserts per second on a single 1-vCPU container.
Q5. What security measures have you implemented (authentication, data protection, etc.)?
Answer: Defense in depth at six layers. (1) Strict OWASP HTTP headers (X-Content-Type-Options, X-Frame-Options=DENY, Referrer-Policy=strict-origin-when-cross-origin) on every static response. (2) Server tokens off and gzip on for both bandwidth and fingerprint reduction. (3) FastAPI Pydantic validation rejects malformed bodies (lat/lon out of range, oversized payloads) before any logic runs. (4) IP-based rate limiting on /v1/demo-request at 30 requests per minute. (5) No secrets in code or logs; the GCS bucket name and DB URL are env vars; the database service account uses workload identity, not a key file. (6) Logs are sanitized: lat/lon are kept (they are public geography), but no PII is collected. TLS 1.3 is provided by Cloud Run by default.
Q6. What are the biggest challenges you faced during development, and how did you solve them?
Answer: Three major challenges. First, SQLite on a stateless filesystem: solved by pulling from GCS on cold start, marking dirty on every write, and pushing back at most every 30 seconds and on SIGTERM. Second, deterministic carbon traces for the demo without a paid API: solved by fitting a closed-form per-region cosine model to public Ember-Energy 2024 averages, with the production hook to swap in a live API as a one-line change. Third, keeping the decision auditable while still being fast: solved by deliberately avoiding a black-box ML model and shipping a transparent four-term linear scorer whose every weighted contribution is persisted to the database.
Q7. How did you test your system, and how do you ensure it is reliable?
Answer: Three test families. Golden-path: 200 simulated requests from Mumbai at midnight UTC; assert chosen region carbon < baseline, latency overhead < 100ms median. Edge cases: Antarctica request, weight collapses to latency-only baseline, region phase hour at solar peak. Failure modes: DB unreachable returns id=null and dashboard surfaces banner; GCS unreachable on DB cold start falls back to empty SQLite and logs a warning; rate-limited 31st request returns 429; invalid body returns 422 from Pydantic before reaching logic. The deploy script curls /healthz on every service after each deploy and aborts on any non-200; if Cloud Run cannot start a new revision the previous revision continues to serve.
Q8. If your system fails in production, how will you handle debugging and recovery?
Answer: Every service writes structured logs to stdout/stderr (timestamp, severity, file:line, function, correlation id), captured by Cloud Logging at the project level. Cloud Trace is enabled, so latency between frontend, backend and DB is broken out per request. Cloud Run preserves the last 100 revisions of every service; rollback is one gcloud run services update-traffic command. The DB recovery story is the strongest: the entire audit log is round-tripped to GCS, which has 99.999999999% durability; even a complete container loss cannot lose more than the last 30 seconds. The /healthz endpoints are wired to Cloud Run liveness so a stuck container is killed and replaced automatically.
Q9. What are the limitations of your project, and how can it be improved further?
Answer: Five limitations. (1) The carbon model is synthetic, fitted to Ember-Energy 2024 averages; production should use ElectricityMap or WattTime live data. (2) The cold-start probability is per-router-instance memory and drifts under multi-instance load; should be moved to a shared store (Memorystore Redis) for accuracy. (3) The cost term assumes Cloud Run pricing; multi-cloud (Lambda, Azure Container Apps) would need pricing tables per provider. (4) The linear scorer trades some optimality for transparency; a learned model could improve the carbon-latency Pareto curve at the tails. (5) The database is single-writer SQLite; replacing the implementation behind the same HTTP contract with Spanner or Firestore is a one-day task when load demands it.
Q10. If you had to deploy this as a real product or startup, what would be your next steps?
Answer: Step 1: integrate a live carbon API (ElectricityMap, $79/month) and re-run the benchmark on real data. Step 2: build a small SDK that lets developers add @greenscale.route() to their existing Cloud Run / Lambda handler, so adoption is two lines of code. Step 3: a hosted multi-tenant control plane on Cloud Run that runs the routing engine for many customers, billed per million decisions. Step 4: integrate sustainability disclosure exports (CSRD-aligned and India BRSR-aligned CSV) directly from the audit table, which is the killer feature for the SME compliance market. Step 5: extend to multi-cloud by adding Lambda and Azure Container Apps adapters, addressing teams running on more than one provider.