// challenge instances for CTF organizers

Don't be the Bad CTF.

Each team is assigned its own microVM, and your docker-compose.yml runs inside it unchanged. We operate the servers in Seoul, Tokyo, Frankfurt and Atlanta.

isolation
1 VM per team
billing
10-minute ticks
integration
CTFd, REST API
tail -f /var/log/chall.run/spawn.log 415 running
sample log · 09:00 is when CTFs start and servers fall over

01 right after the start

Most outages happenin the first minutes.

A made-up timeline, pieced together from public postmortems and our own experience. It's roughly what happens when every team's instance runs on a single server.

  1. Organizers post "good luck, have fun" in #announcements
  2. Challenges unlock. 812 teams press "start instance" in the same second
  3. The one docker host hits load average 97. SSH stops answering
  4. The OOM killer picks the postgres behind web/blog-v2. Of course it does
  5. #general: "is chall down?" (×140)
  6. Someone reboots the box. Every running instance, and every half-written exploit, is gone
  7. Top CTFtime comment: "bad ctf, infra died". You can guess how the weight vote went

$ diff bad-ctf.yml chall.run.yml

+1 microVM per team

A fork bomb in one team's instance doesn't affect other teams. Each VM has its own kernel and cgroup limits, and no VM shares the docker socket.

+Capacity reserved for your event

With a Reserved plan, memory and vCPU on specific hosts are set aside for your start time. No other customer's instances are placed on those hosts.

+Queue instead of failures

Requests above capacity go into a queue rather than failing. CTFd shows players their position and estimated wait.

+TTL and automatic cleanup

You set the lifetime per challenge: 10 minutes for a quick one, a few hours for a long one, with or without player extensions. Expired instances are cleaned up, so forgotten ones don't sit on memory until 3 AM.

+Egress limits per VM

One team running a brute-force script won't slow down the network for the other 811.

02 how it works

Keep your compose filesand your CTFd.

  1. 01

    Push

    challrun push builds your images and deploys them to the regions you choose, from the same compose file you tested locally.

  2. 02

    Connect

    Install the CTFd plugin, or call the REST API from another platform. rCTF or a custom scoreboard works as long as it can make HTTP requests.

  3. 03

    Event day

    Each time a team starts an instance, a new microVM boots with that team's flag injected. We handle host monitoring and incident response.

# sits next to your docker-compose.yml, nothing else changes
name: web/blog-v2
compose: ./docker-compose.yml
expose:
  - service: app
    port: 8080
    as: https   # https://<team>.blog-v2.inst.chall.run
  - service: pwnbox
    port: 31337
    as: tcp     # nc icn1.chall.run 40213
resources:
  memory: 512Mi
  cpu: 0.5
ttl: 45m
flag:
  env: FLAG       # unique per team, injected at spawn
  format: "acme{%s}"
team -- https / nc --> edge.icn1   sni + port map
                          |
          +---------------+---------------+
          v                               v
   host epyc-07                    host epyc-11
   |- fc-7f3a  b4ckd00r          |- fc-c0de  r3kt
   |  `- compose: app, db          |  `- compose: pwnbox
   |- fc-91ab  null_ptr          `- fc-0b5e  0xfe
   `- ...                             `- ...

03 pricing

Credits, countedin 10-minute ticks.

All usage is counted in 10-minute ticks and charged in credits. 1 credit = $0.002, so $10 buys 5,000 credits. There are no seat or platform fees, and on-demand has no minimum spend.

the meter

resourceunitcredits
Memory256 MiB · 10 min1
vCPU (shared)0.25 vCPU · 10 min1
Disk2 GiB per instancefree
beyond that, 48 GiB · 10 min1
Egress20 GB per eventfree
beyond that, per GB (metered every 10 min)varies by region
Image storage10 GiBfree
beyond that, 20 GiB · 10 min1
Ingress, IPv4, TLS, DDoS protectionfree

Each started 10-minute tick is billed. For example, a 512 MiB / 0.5 vCPU instance in Frankfurt costs 4 credits ($0.008) per tick.

regions

regioncompute ×egress (cr/GB)
fra1Frankfurt ×1.002
ams1Amsterdam ×1.002
atl1Atlanta ×0.952
icn1Seoul ×1.1517
nrt1Tokyo ×1.156
sin1Singapore ×1.156
gru1São Paulo soon×1.40tba

on-demand and reserved

Both plans use the same unit prices. Reserved guarantees capacity for your event window, and reserved capacity is billed whether or not it is used.

On-demand Reserved
Unit price Same Same
Capacity Best effort, queued at peak Held on specific hosts for your window
Commitment None Min. 24 h, min. 25,000 credits ($50)
Booking Instant At least 72 h before start
Unused capacity Not billed Billed
Above the reservation — Billed as on-demand
Cancellation — Free until 72 h before start

04 estimate

Enter your event sizeto estimate the cost.

presets
memory per instance
vCPU per instance

ESTIMATE icn1 · On-demand

instances started
4,500
10-min ticks
27,000
credits per tick
4 × 1.15
compute
124,200 cr
egress
340 cr
total $249

124,540 credits · 1 cr = $0.002

About 94 instances running on average, up to ~282 right after the start.

For the first few hours, reserving about 141 GiB / 141 vCPU is a safe choice.

Rough estimate. Instance starts are assumed to cluster early, so peak is set at 3× the average. During the event, actual usage is shown in the dashboard.

05 community support

Free instancesfor small CTFs.

Many CTFs are run by students and volunteers who pay for servers themselves. Events that meet the criteria below can have their instance costs covered from a credit pool funded by sponsors and by chall.run. The limit is 125,000 credits ($250) per event, enough for the mid-size preset in the calculator.

Prize pool
US$2,000 or less in cash, or no prizes
Organizer
student club, university, nonprofit, or volunteer team
Entry
free, with open registration
We ask
use the sponsored instance plugin we provide. It may show the credit pool sponsors' logos in small print under the start-instance button.
apply for support →
sponsors-->credit pool-->community CTFs

Sponsorship goes entirely to instance costs for community CTFs. In supported events, sponsor logos appear in small print under the start-instance button of the sponsored instance plugin.

  • supporter $500 about 25 campus CTFs
  • backer $2,500 about 10 mid-size events
  • founding $10,000+ a year of the pool, plus a seat on grant reviews
sponsor 01open
sponsor 02open
sponsor 03open
sponsor 04open
sponsor 05open
sponsor 06open
become a sponsor →

06 questions

Why microVMs instead of containers?

Players are actively trying to escape sandboxes. Containers share a kernel with other teams on the same host; each microVM has its own. The VMs boot in under a second, so stronger isolation doesn't mean a long wait.

Do I need to change my challenges?

Usually not. If it runs with docker compose up locally, it runs here. Privileged containers and host networking are not supported.

Can I use it without CTFd?

Yes, through the REST API. It has four endpoints: start, extend, stop and status. The CTFd plugin uses the same API.

What happens if credits run out during the event?

We'll let you know when your balance is running low. Even if credits run out, running instances won't be stopped on the spot. Billing can wait. The CTF can't.

What if players attack the infrastructure?

Each VM has egress limits and no network path to other teams' VMs or to the control plane. If you find a VM escape or a similar issue, please report it. Valid reports are rewarded.

Early access is paused.Reach us by email.

$ contact

We're not taking early-access requests while we get the beta ready. For event plans or any questions, send us an email.

support@quickmetal.kr send an email →