免費運算方案的五個迷思與可重跑的重啟演練:不要假設資料會保留
Assume Nothing Persists: Five Free-Tier Myths and a Restart Drill You Can Re-Run
文章整理免費運算方案的五個常見迷思,並提供可重跑的重啟演練,檢查應用程式重啟或重新部署後,標記資料能否讀取。作者建議將資料分為可丟棄、可重建及需持久保存三類,並以寫入與讀取標記的結果判讀狀態。這項演練只反映單一路由、單次測試的結果,不能視為持續可用的保證。
Free compute is easy to start and easy to misread. Your demo works on Friday afternoon. Do you know it works on Monday morning?
Here is one reframe that kills most of these myths at once. A free tier gives you a lease on compute, not a pet server. You re-acquire the machine every single time.
The workflow below assumes only two things: free model access and a free server option. MonkeyCode provides both, and I use them for exactly this kind of pre-flight check.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
I will not tell you what your tier does. I will show you how to find out in ten minutes.
Myth 1: The box you deployed to is not the box you get tomorrow
What developers repeat: It's a small VM, it's fine, I'll SSH in next week.
Cheap check: write a marker, wait, read it back. That's the whole test.
Corrected model: treat the host as a lease. If you cannot recreate the environment with one command, it isn't really yours.
Here is a blunter question. Would you notice if the disk was wiped last night? Most teams find out during an incident, not a drill.
That gap is the entire problem. The drill closes it in about a minute.
Myth 2: Local disk counts as a database when the data is small
What developers repeat: It's forty rows. SQLite on the box is fine.
Small data is not the risk here. Silent loss is.
Cheap check: grep for local writes before you redeploy anything. It is faster than a restart test.
grep -rnE -e 'writeFileSync' -e 'localStorage\.setItem' -e 'sqlite3\.connect' -e 'open\(.*w' \
--include='*.js' --include='*.ts' --include='*.py' . \
| grep -v node_modules | head -40
Expect false positives. That is fine. You want the list, not a verdict.
Corrected model: sort your state into three classes before you host it anywhere.
- Disposable — caches, temp renders, preview thumbnails. Lost is fine.
- Rebuildable — indexes, derived summaries, embeddings. Lost is expensive.
- Durable — user records, payments, audit trails. Lost is an incident.
Only class 1 belongs on the box. Class 2 belongs in a job. Class 3 belongs somewhere with a backup story.
Myth 3: Free means weaker, so there is nothing to measure
What developers repeat: Free model access is a toy, I'll evaluate properly when I pay.
Cheap check: pull ten prompts from your own backlog. Score pass or fail by hand. Repeat next week with the same rubric.
Corrected model: free describes price, not a capability tier. It tells you nothing about which model answers, what limits apply, or whether that changes next month.
So measure your task, on your prompts, against your definition of done. Nothing else transfers between contexts.
This is where free model access actually earns its place. It lets you run the harness until the harness becomes boring.
Keep the evaluation model-agnostic on purpose.
- Store prompts in a file, not in code.
- Store expected outcomes as plain text.
- Print a pass rate, not a vibe.
Do that once, and a model swap becomes a one-line config change. That is the artifact worth keeping.
Myth 4: A green health check means the app is ready
What developers repeat: It returned 200, so we're back.
Cheap check: after a restart, hit your health route and your data route in that order. Time each one.
Corrected model: liveness and readiness answer different questions. The process is up is not the same as the dependencies are up.
A process can boot in a second and still fail its first query. Then your drill reports data loss, when the truth is impatience.
So wait on a probe that touches the real dependency. Then read the marker.
# wait until the app can answer a data-shaped question
for i in $(seq 1 20); do
code=$(curl -s -o /dev/null -w '%{http_code}' "$BASE_URL/api/ready")
[ "$code" = "200" ] && break
sleep 5
done
echo "ready check: $code"
Adjust the loop to your app. Do not blindly copy my counts.
Myth 5: Leaving the free tier is just a deploy
What developers repeat: We'll flip to paid on launch day, it's a config change.
Cheap check: time a full state export and import. Do it weeks before you need it.
Corrected model: migration is a state move, not a button. The app moves in minutes. The data moves in an afternoon, or a week.
If you cannot export durable state today, you cannot migrate on launch day. That's not pessimism, it's arithmetic.
The drill: two commands and a verdict table
The drill needs one tiny route from your app.
-
POST /api/markerstores an id. -
GET /api/marker?id=...returns it, or a 404.
That route is five lines in most frameworks. Then run this template and adapt the paths.
#!/usr/bin/env bash
# drill.sh — does my app survive a restart? Template: adapt BASE_URL and routes.
set -uo pipefail
BASE_URL="${BASE_URL:?export BASE_URL=https://your-app.example}"
ID_FILE="$PWD/.drill-id"
MODE="${1:-write}"
case "$MODE" in
write)
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-$$"
printf '%s' "$RUN_ID" > "$ID_FILE"
PAYLOAD=$(printf '{"id":"%s"}' "$RUN_ID")
printf 'write status: '
curl -sS -X POST "$BASE_URL/api/marker" \
-H 'content-type: application/json' \
-d "$PAYLOAD" \
-o "write-$RUN_ID.json" -w '%{http_code}\n'
printf 'run id: %s\n' "$RUN_ID"
;;
read)
RUN_ID="$(cat "$ID_FILE")"
printf 'read status: '
curl -sS "$BASE_URL/api/marker?id=$RUN_ID" \
-o "read-$RUN_ID.json" -w '%{http_code}\n'
printf 'read body: '; cat "read-$RUN_ID.json"; printf '\n'
;;
*)
printf 'usage: %s [write|read]\n' "$0"; exit 2 ;;
esac
Run it in three steps.
BASE_URL=https://your-app.example ./drill.sh write- Restart or redeploy the app using the platform's own control.
BASE_URL=https://your-app.example ./drill.sh read
Then read the table, not your hopes.
| Read status | Body | Likely cause | Next step |
|---|---|---|---|
200 |
contains your run id | State survived the restart | Record the date, re-run monthly |
200 |
null or empty |
Storage reset, or the route returns defaults | Move durable state off the box |
404 |
anything | Route missing, or old code came back | Check the deployed revision |
000 |
none | No connection at all | Fix the wake step, not the app |
One written line in a notes file beats an argument in a pull request.
Who should not use this approach
Be honest with yourself here.
- Teams with uptime commitments. A lease is not an SLA, and no drill changes that.
- Regulated or personal data. Verify storage location and retention before hosting anything.
- Apps with no external state store. Build that first. The drill will only confirm the gap.
- Anyone who won't re-run it. A single green run is an anecdote, not evidence.
Limits, stated plainly
The drill proves what happened once, on one route, on one day. That's a sample, not a guarantee.
Free tiers change without notice. So does your app. Neither of those is a bug in the method.
Re-run the drill after every deploy that touches storage or startup. It costs a minute and saves a weekend.
If you want a low-stakes place to try this, free model access to write the marker route plus the free server option to host it is enough. Start small. Then go break it on purpose.
來源:DEV Community · dev.to