Summary
This experiment investigates docker build layer caching. Fractional factorial of 5 Docker build parameters for build time and image size.
The design varies 5 factors: build cache mode, ranging from inline to registry, max layers (layers), ranging from 5 to 30, squash enabled, ranging from off to on, build arg count (args), ranging from 0 to 10, and multistage stages (stages), ranging from 1 to 5. The goal is to optimize 2 responses: build time sec (sec) (minimize) and image size mb (MB) (minimize). Fixed conditions held constant across all runs include builder = buildkit, registry = ecr.
A fractional factorial design reduces the number of runs from 32 to 8 by deliberately confounding higher-order interactions. This is ideal for screening — identifying which of the 5 factors matter most before investing in a full study.
Key Findings
For build time sec, the most influential factors were build arg count (44.8%), multistage stages (23.5%), squash enabled (18.6%). The best observed value was 52.0 (at build cache mode = registry, max layers = 30, squash enabled = on).
For image size mb, the most influential factors were squash enabled (29.8%), build arg count (26.8%), build cache mode (25.2%). The best observed value was 328.0 (at build cache mode = registry, max layers = 30, squash enabled = on).
Recommended Next Steps
- Follow up with a response surface design (CCD or Box-Behnken) on the top 3–4 factors to model curvature and find the true optimum.
- Consider whether any fixed factors should be varied in a future study.
- The screening results can guide factor reduction — drop factors contributing less than 5% and re-run with a smaller, more focused design.
Experimental Setup
Factors
| Factor | Low | High | Unit |
build_cache_mode | inline | registry | |
max_layers | 5 | 30 | layers |
squash_enabled | off | on | |
build_arg_count | 0 | 10 | args |
multistage_stages | 1 | 5 | stages |
Fixed: builder = buildkit, registry = ecr
Responses
| Response | Direction | Unit |
build_time_sec | ↓ minimize | sec |
image_size_mb | ↓ minimize | MB |
Configuration
{
"metadata": {
"name": "Docker Build Layer Caching",
"description": "Fractional factorial of 5 Docker build parameters for build time and image size"
},
"factors": [
{
"name": "build_cache_mode",
"levels": [
"inline",
"registry"
],
"type": "categorical",
"unit": ""
},
{
"name": "max_layers",
"levels": [
"5",
"30"
],
"type": "continuous",
"unit": "layers"
},
{
"name": "squash_enabled",
"levels": [
"off",
"on"
],
"type": "categorical",
"unit": ""
},
{
"name": "build_arg_count",
"levels": [
"0",
"10"
],
"type": "continuous",
"unit": "args"
},
{
"name": "multistage_stages",
"levels": [
"1",
"5"
],
"type": "continuous",
"unit": "stages"
}
],
"fixed_factors": {
"builder": "buildkit",
"registry": "ecr"
},
"responses": [
{
"name": "build_time_sec",
"optimize": "minimize",
"unit": "sec"
},
{
"name": "image_size_mb",
"optimize": "minimize",
"unit": "MB"
}
],
"settings": {
"operation": "fractional_factorial",
"test_script": "use_cases/80_docker_build_layer_caching/sim.sh"
}
}
Experimental Matrix
The Fractional Factorial Design produces 8 runs. Each row is one experiment with specific factor settings.
| Run | build_cache_mode | max_layers | squash_enabled | build_arg_count | multistage_stages |
| 1 | inline | 30 | on | 0 | 1 |
| 2 | registry | 5 | off | 0 | 1 |
| 3 | registry | 30 | off | 10 | 1 |
| 4 | registry | 30 | on | 10 | 5 |
| 5 | inline | 30 | off | 0 | 5 |
| 6 | registry | 5 | on | 0 | 5 |
| 7 | inline | 5 | off | 10 | 5 |
| 8 | inline | 5 | on | 10 | 1 |
Step-by-Step Workflow
1
Preview the design
$ doe info --config use_cases/80_docker_build_layer_caching/config.json
2
Generate the runner script
$ doe generate --config use_cases/80_docker_build_layer_caching/config.json \
--output use_cases/80_docker_build_layer_caching/results/run.sh --seed 42
3
Execute the experiments
$ bash use_cases/80_docker_build_layer_caching/results/run.sh
4
Analyze results
$ doe analyze --config use_cases/80_docker_build_layer_caching/config.json
5
Get optimization recommendations
$ doe optimize --config use_cases/80_docker_build_layer_caching/config.json
6
Multi-objective optimization
With 2 competing responses, use --multi to find the best compromise via Derringer–Suich desirability.
$ doe optimize --config use_cases/80_docker_build_layer_caching/config.json --multi
7
Generate the HTML report
$ doe report --config use_cases/80_docker_build_layer_caching/config.json \
--output use_cases/80_docker_build_layer_caching/results/report.html
Features Exercised
| Feature | Value |
| Design type | fractional_factorial |
| Factor types | continuous (3), categorical (2) |
| Arg style | double-dash |
| Responses | 2 (build_time_sec ↓, image_size_mb ↓) |
| Total runs | 8 |
Analysis Results
Generated from actual experiment runs using the DOE Helper Tool.
Response: build_time_sec
Top factors: build_arg_count (44.8%), multistage_stages (23.5%), squash_enabled (18.6%).
ANOVA
| Source | DF | SS | MS | F | p-value |
| Source | DF | SS | MS | F | p-value |
| build_cache_mode | 1 | 112.5000 | 112.5000 | 0.104 | 0.7603 |
| max_layers | 1 | 98.0000 | 98.0000 | 0.090 | 0.7757 |
| squash_enabled | 1 | 840.5000 | 840.5000 | 0.776 | 0.4187 |
| build_arg_count | 1 | 4900.5000 | 4900.5000 | 4.525 | 0.0867 |
| multistage_stages | 1 | 1352.0000 | 1352.0000 | 1.248 | 0.3147 |
| build_cache_mode*max_layers | 1 | 4900.5000 | 4900.5000 | 4.525 | 0.0867 |
| build_cache_mode*squash_enabled | 1 | 1352.0000 | 1352.0000 | 1.248 | 0.3147 |
| build_cache_mode*build_arg_count | 1 | 98.0000 | 98.0000 | 0.090 | 0.7757 |
| build_cache_mode*multistage_stages | 1 | 840.5000 | 840.5000 | 0.776 | 0.4187 |
| max_layers*squash_enabled | 1 | 1984.5000 | 1984.5000 | 1.832 | 0.2338 |
| max_layers*build_arg_count | 1 | 112.5000 | 112.5000 | 0.104 | 0.7603 |
| max_layers*multistage_stages | 1 | 722.0000 | 722.0000 | 0.667 | 0.4513 |
| squash_enabled*build_arg_count | 1 | 722.0000 | 722.0000 | 0.667 | 0.4513 |
| squash_enabled*multistage_stages | 1 | 112.5000 | 112.5000 | 0.104 | 0.7603 |
| build_arg_count*multistage_stages | 1 | 1984.5000 | 1984.5000 | 1.832 | 0.2338 |
| Error | (Lenth | PSE) | 5 | 5415.0000 | 1083.0000 |
| Total | 7 | 10010.0000 | 1430.0000 | | |
Pareto Chart
Main Effects Plot
Normal Probability Plot of Effects
Half-Normal Plot of Effects
Model Diagnostics
Response: image_size_mb
Top factors: squash_enabled (29.8%), build_arg_count (26.8%), build_cache_mode (25.2%).
ANOVA
| Source | DF | SS | MS | F | p-value |
| Source | DF | SS | MS | F | p-value |
| build_cache_mode | 1 | 20402.0000 | 20402.0000 | 2.615 | 0.1668 |
| max_layers | 1 | 968.0000 | 968.0000 | 0.124 | 0.7390 |
| squash_enabled | 1 | 28560.5000 | 28560.5000 | 3.660 | 0.1139 |
| build_arg_count | 1 | 23112.5000 | 23112.5000 | 2.962 | 0.1459 |
| multistage_stages | 1 | 5202.0000 | 5202.0000 | 0.667 | 0.4513 |
| build_cache_mode*max_layers | 1 | 23112.5000 | 23112.5000 | 2.962 | 0.1459 |
| build_cache_mode*squash_enabled | 1 | 5202.0000 | 5202.0000 | 0.667 | 0.4513 |
| build_cache_mode*build_arg_count | 1 | 968.0000 | 968.0000 | 0.124 | 0.7390 |
| build_cache_mode*multistage_stages | 1 | 28560.5000 | 28560.5000 | 3.660 | 0.1139 |
| max_layers*squash_enabled | 1 | 1922.0000 | 1922.0000 | 0.246 | 0.6407 |
| max_layers*build_arg_count | 1 | 20402.0000 | 20402.0000 | 2.615 | 0.1668 |
| max_layers*multistage_stages | 1 | 5724.5000 | 5724.5000 | 0.734 | 0.4308 |
| squash_enabled*build_arg_count | 1 | 5724.5000 | 5724.5000 | 0.734 | 0.4308 |
| squash_enabled*multistage_stages | 1 | 20402.0000 | 20402.0000 | 2.615 | 0.1668 |
| build_arg_count*multistage_stages | 1 | 1922.0000 | 1922.0000 | 0.246 | 0.6407 |
| Error | (Lenth | PSE) | 5 | 39015.0000 | 7803.0000 |
| Total | 7 | 85891.5000 | 12270.2143 | | |
Pareto Chart
Main Effects Plot
Normal Probability Plot of Effects
Half-Normal Plot of Effects
Model Diagnostics
Response Surface Plots
3D surfaces fitted with quadratic RSM. Red dots are observed data points.
build time sec build arg count vs multistage stages
build time sec max layers vs build arg count
build time sec max layers vs multistage stages
image size mb build arg count vs multistage stages
image size mb max layers vs build arg count
image size mb max layers vs multistage stages
Multi-Objective Optimization
When responses compete, Derringer–Suich desirability finds the best compromise.
Each response is scaled to a 0–1 desirability, then combined via a weighted geometric mean.
Overall Desirability
D = 0.9545
Per-Response Desirability
| Response | Weight | Desirability | Predicted | Dir |
build_time_sec |
1.5 |
|
52.00 0.9545 52.00 sec |
↓ |
image_size_mb |
1.0 |
|
328.00 0.9545 328.00 MB |
↓ |
Recommended Settings
| Factor | Value |
build_cache_mode | registry |
max_layers | 30 layers |
squash_enabled | on |
build_arg_count | 10 args |
multistage_stages | 5 stages |
Source: from observed run #6
Trade-off Summary
Sacrifice = how much worse than single-objective best.
| Response | Predicted | Best Observed | Sacrifice |
image_size_mb | 328.00 | 328.00 | +0.00 |
Top 3 Runs by Desirability
| Run | D | Factor Settings |
| #2 | 0.5595 | build_cache_mode=inline, max_layers=5, squash_enabled=on, build_arg_count=10, multistage_stages=1 |
| #4 | 0.5494 | build_cache_mode=registry, max_layers=5, squash_enabled=off, build_arg_count=0, multistage_stages=1 |
Model Quality
| Response | R² | Type |
image_size_mb | 0.7341 | linear |
Full Multi-Objective Output
============================================================
MULTI-OBJECTIVE OPTIMIZATION
Method: Derringer-Suich Desirability Function
============================================================
Overall desirability: D = 0.9545
Response Weight Desirability Predicted Direction
---------------------------------------------------------------------
build_time_sec 1.5 0.9545 52.00 sec ↓
image_size_mb 1.0 0.9545 328.00 MB ↓
Recommended settings:
build_cache_mode = registry
max_layers = 30 layers
squash_enabled = on
build_arg_count = 10 args
multistage_stages = 5 stages
(from observed run #6)
Trade-off summary:
build_time_sec: 52.00 (best observed: 52.00, sacrifice: +0.00)
image_size_mb: 328.00 (best observed: 328.00, sacrifice: +0.00)
Model quality:
build_time_sec: R² = 0.3753 (linear)
image_size_mb: R² = 0.7341 (linear)
Top 3 observed runs by overall desirability:
1. Run #6 (D=0.9545): build_cache_mode=registry, max_layers=30, squash_enabled=on, build_arg_count=10, multistage_stages=5
2. Run #2 (D=0.5595): build_cache_mode=inline, max_layers=5, squash_enabled=on, build_arg_count=10, multistage_stages=1
3. Run #4 (D=0.5494): build_cache_mode=registry, max_layers=5, squash_enabled=off, build_arg_count=0, multistage_stages=1
Full Analysis Output
=== Main Effects: build_time_sec ===
Factor Effect Std Error % Contribution
--------------------------------------------------------------
build_arg_count 49.5000 13.3697 44.8%
multistage_stages 26.0000 13.3697 23.5%
squash_enabled 20.5000 13.3697 18.6%
build_cache_mode 7.5000 13.3697 6.8%
max_layers -7.0000 13.3697 6.3%
=== ANOVA Table: build_time_sec ===
Source DF SS MS F p-value
-----------------------------------------------------------------------------
build_cache_mode 1 112.5000 112.5000 0.104 0.7603
max_layers 1 98.0000 98.0000 0.090 0.7757
squash_enabled 1 840.5000 840.5000 0.776 0.4187
build_arg_count 1 4900.5000 4900.5000 4.525 0.0867
multistage_stages 1 1352.0000 1352.0000 1.248 0.3147
build_cache_mode*max_layers 1 4900.5000 4900.5000 4.525 0.0867
build_cache_mode*squash_enabled 1 1352.0000 1352.0000 1.248 0.3147
build_cache_mode*build_arg_count 1 98.0000 98.0000 0.090 0.7757
build_cache_mode*multistage_stages 1 840.5000 840.5000 0.776 0.4187
max_layers*squash_enabled 1 1984.5000 1984.5000 1.832 0.2338
max_layers*build_arg_count 1 112.5000 112.5000 0.104 0.7603
max_layers*multistage_stages 1 722.0000 722.0000 0.667 0.4513
squash_enabled*build_arg_count 1 722.0000 722.0000 0.667 0.4513
squash_enabled*multistage_stages 1 112.5000 112.5000 0.104 0.7603
build_arg_count*multistage_stages 1 1984.5000 1984.5000 1.832 0.2338
Error (Lenth PSE) 5 5415.0000 1083.0000
Total 7 10010.0000 1430.0000
Note: Error estimated using Lenth's pseudo-standard-error (unreplicated design)
=== Interaction Effects: build_time_sec ===
Factor A Factor B Interaction % Contribution
------------------------------------------------------------------------
build_cache_mode max_layers -49.5000 22.6%
max_layers squash_enabled 31.5000 14.4%
build_arg_count multistage_stages -31.5000 14.4%
build_cache_mode squash_enabled 26.0000 11.9%
build_cache_mode multistage_stages 20.5000 9.4%
max_layers multistage_stages 19.0000 8.7%
squash_enabled build_arg_count -19.0000 8.7%
max_layers build_arg_count -7.5000 3.4%
squash_enabled multistage_stages 7.5000 3.4%
build_cache_mode build_arg_count 7.0000 3.2%
=== Summary Statistics: build_time_sec ===
build_cache_mode:
Level N Mean Std Min Max
------------------------------------------------------------
inline 4 121.2500 25.7730 91.0000 146.0000
registry 4 128.7500 51.3314 52.0000 159.0000
max_layers:
Level N Mean Std Min Max
------------------------------------------------------------
30 4 128.5000 33.7589 91.0000 159.0000
5 4 121.5000 46.5224 52.0000 149.0000
squash_enabled:
Level N Mean Std Min Max
------------------------------------------------------------
off 4 114.7500 46.6074 52.0000 159.0000
on 4 135.2500 29.7363 91.0000 155.0000
build_arg_count:
Level N Mean Std Min Max
------------------------------------------------------------
0 4 100.2500 40.2772 52.0000 149.0000
10 4 149.7500 8.9954 139.0000 159.0000
multistage_stages:
Level N Mean Std Min Max
------------------------------------------------------------
1 4 112.0000 49.6857 52.0000 159.0000
5 4 138.0000 20.4287 109.0000 155.0000
=== Main Effects: image_size_mb ===
Factor Effect Std Error % Contribution
--------------------------------------------------------------
squash_enabled 119.5000 39.1635 29.8%
build_arg_count 107.5000 39.1635 26.8%
build_cache_mode -101.0000 39.1635 25.2%
multistage_stages -51.0000 39.1635 12.7%
max_layers -22.0000 39.1635 5.5%
=== ANOVA Table: image_size_mb ===
Source DF SS MS F p-value
-----------------------------------------------------------------------------
build_cache_mode 1 20402.0000 20402.0000 2.615 0.1668
max_layers 1 968.0000 968.0000 0.124 0.7390
squash_enabled 1 28560.5000 28560.5000 3.660 0.1139
build_arg_count 1 23112.5000 23112.5000 2.962 0.1459
multistage_stages 1 5202.0000 5202.0000 0.667 0.4513
build_cache_mode*max_layers 1 23112.5000 23112.5000 2.962 0.1459
build_cache_mode*squash_enabled 1 5202.0000 5202.0000 0.667 0.4513
build_cache_mode*build_arg_count 1 968.0000 968.0000 0.124 0.7390
build_cache_mode*multistage_stages 1 28560.5000 28560.5000 3.660 0.1139
max_layers*squash_enabled 1 1922.0000 1922.0000 0.246 0.6407
max_layers*build_arg_count 1 20402.0000 20402.0000 2.615 0.1668
max_layers*multistage_stages 1 5724.5000 5724.5000 0.734 0.4308
squash_enabled*build_arg_count 1 5724.5000 5724.5000 0.734 0.4308
squash_enabled*multistage_stages 1 20402.0000 20402.0000 2.615 0.1668
build_arg_count*multistage_stages 1 1922.0000 1922.0000 0.246 0.6407
Error (Lenth PSE) 5 39015.0000 7803.0000
Total 7 85891.5000 12270.2143
Note: Error estimated using Lenth's pseudo-standard-error (unreplicated design)
=== Interaction Effects: image_size_mb ===
Factor A Factor B Interaction % Contribution
------------------------------------------------------------------------
build_cache_mode multistage_stages 119.5000 17.8%
build_cache_mode max_layers -107.5000 16.0%
max_layers build_arg_count 101.0000 15.1%
squash_enabled multistage_stages -101.0000 15.1%
max_layers multistage_stages -53.5000 8.0%
squash_enabled build_arg_count 53.5000 8.0%
build_cache_mode squash_enabled -51.0000 7.6%
max_layers squash_enabled 31.0000 4.6%
build_arg_count multistage_stages -31.0000 4.6%
build_cache_mode build_arg_count 22.0000 3.3%
=== Summary Statistics: image_size_mb ===
build_cache_mode:
Level N Mean Std Min Max
------------------------------------------------------------
inline 4 516.7500 120.4447 431.0000 687.0000
registry 4 415.7500 85.5740 328.0000 526.0000
max_layers:
Level N Mean Std Min Max
------------------------------------------------------------
30 4 477.2500 51.2535 431.0000 526.0000
5 4 455.2500 160.2527 328.0000 687.0000
squash_enabled:
Level N Mean Std Min Max
------------------------------------------------------------
off 4 406.5000 52.3609 328.0000 435.0000
on 4 526.0000 127.9401 374.0000 687.0000
build_arg_count:
Level N Mean Std Min Max
------------------------------------------------------------
0 4 412.5000 81.4146 328.0000 517.0000
10 4 520.0000 119.5742 432.0000 687.0000
multistage_stages:
Level N Mean Std Min Max
------------------------------------------------------------
1 4 491.7500 151.4318 328.0000 687.0000
5 4 440.7500 62.9676 374.0000 526.0000
Optimization Recommendations
=== Optimization: build_time_sec ===
Direction: minimize
Best observed run: #6
build_cache_mode = registry
max_layers = 30
squash_enabled = on
build_arg_count = 10
multistage_stages = 5
Value: 52.0
RSM Model (linear, R² = 0.6111, Adj R² = -0.3610):
Coefficients:
intercept +125.0000
build_cache_mode +1.2500
max_layers -8.5000
squash_enabled +0.5000
build_arg_count -12.2500
multistage_stages -23.2500
Predicted optimum (from linear model, at observed points):
build_cache_mode = registry
max_layers = 5
squash_enabled = off
build_arg_count = 0
multistage_stages = 1
Predicted value: 169.7500
Surface optimum (via L-BFGS-B, linear model):
build_cache_mode = inline
max_layers = 30
squash_enabled = off
build_arg_count = 10
multistage_stages = 5
Predicted value: 79.2500
Model quality: Moderate fit — use predictions directionally, not precisely.
Factor importance:
1. multistage_stages (effect: -46.5, contribution: 50.8%)
2. build_arg_count (effect: -24.5, contribution: 26.8%)
3. max_layers (effect: 17.0, contribution: 18.6%)
4. build_cache_mode (effect: 2.5, contribution: 2.7%)
5. squash_enabled (effect: 1.0, contribution: 1.1%)
=== Optimization: image_size_mb ===
Direction: minimize
Best observed run: #6
build_cache_mode = registry
max_layers = 30
squash_enabled = on
build_arg_count = 10
multistage_stages = 5
Value: 328.0
RSM Model (linear, R² = 0.4190, Adj R² = -1.0334):
Coefficients:
intercept +466.2500
build_cache_mode -36.0000
max_layers +4.0000
squash_enabled +12.5000
build_arg_count -52.7500
multistage_stages -15.7500
Predicted optimum (from linear model, at observed points):
build_cache_mode = inline
max_layers = 30
squash_enabled = on
build_arg_count = 0
multistage_stages = 1
Predicted value: 587.2500
Surface optimum (via L-BFGS-B, linear model):
build_cache_mode = registry
max_layers = 5
squash_enabled = off
build_arg_count = 10
multistage_stages = 5
Predicted value: 345.2500
Model quality: Weak fit — consider adding center points or using a different design.
Factor importance:
1. build_arg_count (effect: -105.5, contribution: 43.6%)
2. build_cache_mode (effect: -72.0, contribution: 29.8%)
3. multistage_stages (effect: -31.5, contribution: 13.0%)
4. squash_enabled (effect: 25.0, contribution: 10.3%)
5. max_layers (effect: -8.0, contribution: 3.3%)