Skip to main content
Power schedules determine how AFL++ allocates fuzzing effort across queue entries. Different schedules can significantly impact fuzzing effectiveness depending on your target.

What Are Power Schedules?

When AFL++ selects a test case from the queue, it decides how many fuzzing attempts to perform on it. The power schedule is the algorithm that makes this decision. Different schedules optimize for:
  • Fast coverage growth (explore mode)
  • Deep path exploration (exploit mode)
  • Rare edge discovery
  • Balanced approaches

Available Schedules

Select a power schedule with the -p option:
afl-fuzz -i input -o output -p explore -- ./target @@

explore (default)

Balanced schedule that favors finding new paths quickly while still exploring existing ones.
Best for: General-purpose fuzzing, initial campaigns, unknown targets
afl-fuzz -i input -o output -p explore -- ./target @@

fast

Prioritizes quick execution and rapid iteration through the queue.
Best for: Targets with fast execution, large initial corpus, time-constrained fuzzing
afl-fuzz -i input -o output -p fast -- ./target @@

coe (Cut-Off Exponential)

AFLfast schedule that favors recently discovered paths.
Best for: Targets where recent discoveries are likely to lead to more findings
afl-fuzz -i input -o output -p coe -- ./target @@

lin (Linear)

AFLfast schedule with linear favoritism.
Best for: Balanced exploration without extreme bias
afl-fuzz -i input -o output -p lin -- ./target @@

quad (Quadratic)

AFLfast schedule with quadratic favoritism toward recent paths.
Best for: Aggressive exploitation of recent discoveries
afl-fuzz -i input -o output -p quad -- ./target @@

exploit

Aggressively exploits promising paths, spending more time on high-value inputs.
Best for: Targets where deep exploration of specific paths is valuable, mature campaigns
afl-fuzz -i input -o output -p exploit -- ./target @@

rare

Focuses on rare edges and infrequently executed paths.
Best for: Finding edge cases, hard-to-reach code, targets with many conditional branches
afl-fuzz -i input -o output -p rare -- ./target @@
For parallel fuzzing campaigns, distribute power schedules across instances:
# Main fuzzer with default explore schedule
afl-fuzz -M main -i input -o output -p explore -- ./target @@
Run each power schedule with a different instance to maximize path diversity.

MOpt Mutator

MOpt (Mutation Optimizer) is an adaptive mutation algorithm that learns which mutation strategies work best for your target.

Enabling MOpt

Use the -L option to enable MOpt:
afl-fuzz -L 0 -i input -o output -- ./target @@
-L
integer
Set MOpt mode:
  • 0: Enable MOpt mutator
  • Default: MOpt disabled

How MOpt Works

MOpt uses a Particle Swarm Optimization (PSO) algorithm to:
  1. Track effectiveness of different mutation operators
  2. Dynamically adjust probability of using each operator
  3. Learn optimal mutation strategies during fuzzing
  4. Adapt to target-specific characteristics

When to Use MOpt

Use MOpt When

  • Fuzzing complex targets with specific patterns
  • Long-running campaigns (MOpt needs time to learn)
  • You have diverse mutation needs
  • Target responds differently to mutation types

Skip MOpt When

  • Short fuzzing runs (< 30 minutes)
  • Very simple targets
  • Custom mutators already optimized
  • Need maximum speed (MOpt has small overhead)

MOpt in Parallel Campaigns

Allocate ~10% of fuzzer instances to MOpt:
# 10 total instances = 1 MOpt instance
afl-fuzz -M main -i input -o output -- ./target @@
afl-fuzz -S mopt1 -L 0 -i input -o output -- ./target @@
afl-fuzz -S secondary2 -i input -o output -p fast -- ./target @@
afl-fuzz -S secondary3 -i input -o output -p coe -- ./target @@
# ... 6 more standard instances

Cycle Schedules

Switch to a different schedule every time a cycle is finished:
export AFL_CYCLE_SCHEDULES=1
afl-fuzz -i input -o output -- ./target @@
AFL_CYCLE_SCHEDULES
boolean
Automatically rotate through different power schedules after each queue cycle completes.
This can be unpredictable. Better to run multiple instances with different schedules.

AFLfast Integration

AFL++ integrates AFLfast power schedules (coe, lin, quad) from the research paper:
Marcel Böhme. “Coverage-based Greybox Fuzzing as Markov Chain.” CCS 2016.
These schedules assign higher energy to:
  • Low-frequency paths: Rarely executed code
  • Recently discovered paths: Fresh queue entries
  • Shorter execution paths: Faster iterations

Comparison Table

ScheduleSpeedExplorationExploitationBest For
exploreMediumHighMediumGeneral purpose, default
fastHighMediumLowQuick iterations, large corpus
coeMediumHighMediumRecent discoveries
linMediumMediumMediumBalanced approach
quadMediumLowHighAggressive exploitation
exploitLowLowHighDeep path exploration
rareLowHighLowEdge cases, rare paths

Best Practices

Use the default explore schedule unless you have specific requirements:
afl-fuzz -i input -o output -- ./target @@
Distribute all schedules across instances for maximum diversity:
  • 1 main instance: explore
  • Secondaries: fast, coe, lin, quad, exploit, rare
  • Add MOpt to ~10% of instances
Use fast or explore for quick coverage:
afl-fuzz -i input -o output -p fast -- ./target @@
Add more exploit and rare instances to find deeper bugs:
afl-fuzz -S exploit1 -i input -o output -p exploit -- ./target @@
afl-fuzz -S rare1 -i input -o output -p rare -- ./target @@

Performance Impact

Power schedules have minimal CPU overhead but significantly impact fuzzing strategy:
  • CPU overhead: < 1%
  • Strategy impact: Can change coverage growth by 20-50%
  • Depends on target: Some targets benefit more from specific schedules
Experiment with different schedules on your target. Monitor paths total and uniq crashes in the AFL++ UI to see which schedules perform best.

Custom Mutators

Implement domain-specific mutations

Parallel Fuzzing

Run multiple instances efficiently

Environment Variables

Fine-tune AFL++ behavior

Dictionaries

Provide syntax hints to fuzzer

Build docs developers (and LLMs) love