Daily Fantasy · dfs
How to Build a DFS Optimizer: The Math Explained
By Odds Reference Published July 19, 2026 Updated July 25, 2026 Fact-checked by Odds Reference Editorial Editorial Policy
Last Updated: July 25, 2026
A DFS lineup optimizer is software that solves a constrained math problem: pick the combination of players that maximizes projected fantasy points without exceeding the salary cap or breaking roster rules. Every mainstream optimizer, free or paid, solves this same underlying problem using linear programming.
Key Takeaways
- A DFS optimizer is a Mixed Integer Linear Programming (MILP) solver: it treats each player as a binary yes/no variable and finds the combination that maximizes projected points under a set of constraints.
- The three required constraints are salary cap, roster position requirements, and (usually) a maximum players-per-team limit — everything else is optional refinement.
- Free open-source solvers like Google OR-Tools and PuLP/CBC handle the actual optimization math; the real engineering work is projections, salary data, and constraint formatting.
- Writing the MILP solve yourself only gets you to parity with every free tool already on the market — the engineering lift that actually separates builds is projection quality, ownership modeling, and correlation logic layered on top, not the base solver.
- A basic MILP optimizer has no concept of correlation or ownership by default — both require deliberately added constraints, which is where GPP-focused optimizers diverge from simple cash-game builders, and where a DIY build takes meaningfully longer to reach parity with a paid tool.
What Problem Is a DFS Optimizer Actually Solving?
A DFS optimizer solves a constrained optimization problem: find the subset of players from a pool that maximizes total projected fantasy points, subject to a fixed salary budget and roster-position rules. This is formally a knapsack-style problem, solved in practice with Mixed Integer Linear Programming (MILP).
MILP is well-established outside DFS — it’s the same technique used for airline crew scheduling, supply-chain routing, and portfolio allocation. Applied to DFS, the “items” are players, the “weight” is salary, and the “value” is projected fantasy points. The optimizer’s job is to fill the salary-cap knapsack with the highest-projected-points combination of players that also satisfies position requirements — a search space too large to brute-force by hand for anything beyond a tiny slate.
How Does Linear Programming Apply to DFS?
Linear programming applies to DFS by representing each player as a binary decision variable — 1 if rostered, 0 if not — and defining an objective function (total projected points) that the solver maximizes subject to linear constraints like the salary cap.
Formally, for a player pool of n players, each with projected points p_i and salary s_i, the optimizer solves:
Maximize: Σ (p_i × x_i) for all players i Subject to: Σ (s_i × x_i) ≤ Salary Cap, and roster-position counts satisfied Where: x_i ∈ {0, 1} for every player i
The binary constraint (x_i must be exactly 0 or 1, not a fraction like 0.5) is what makes this an integer program rather than a plain linear one — you can’t roster 60% of a player. That integer restriction is also what makes the problem meaningfully harder to solve than a continuous linear program, which is why dedicated MILP solvers exist rather than simple linear algebra.
What Constraints Does a DFS Optimizer Need?
A working DFS optimizer needs, at minimum, three constraint types: a total salary cap, exact position-count requirements, and typically a limit on how many players can come from a single real-world team. Everything beyond these three is an optional refinement layer.
| Constraint | Plain English | Example (DraftKings NFL) |
|---|---|---|
| Salary cap | Total roster cost can’t exceed the budget | Σ salary ≤ $50,000 |
| Position counts | Exact number of players per slot | 1 QB, 2 RB, 3 WR, 1 TE, 1 FLEX, 1 DST |
| Team limit | Cap players from one real-world team | ≤ 8 players from any single NFL team |
| Flex eligibility | FLEX slot must be filled by an eligible position | FLEX ∈ {RB, WR, TE} |
| Exposure cap (multi-lineup) | Limit how often a player appears across your entry set | Player X in ≤ 40% of submitted lineups |
| Stack/correlation rule | Force or bias toward same-game player pairs | QB + at least 1 pass-catcher from same team |
The first four constraints are effectively mandatory to produce a legal, contest-compliant lineup. Exposure caps and stacking rules are what separate a basic single-lineup optimizer from a serious multi-lineup GPP tool — they require modeling relationships between lineups or between players, not just constraints on a single roster.
Coding the salary cap and position-count constraints correctly is the easy part; getting FLEX eligibility and team limits right is where DIY builds most often produce a lineup that validates in your own code but gets rejected at entry. If you want to sanity-check an allocation before you write a single constraint, our DFS salary cap allocator runs the same cap-and-position math described in the table above — it’s built from the same $50,000 DraftKings / $60,000 FanDuel cap structure your solver needs to encode, and shows that a 9-player DraftKings NFL roster averages roughly $5,500-$5,600 per slot before any optimization happens, which is the baseline your objective function has to beat.
How Do You Actually Build One?
Building a basic optimizer is a five-part process: assemble a player pool with projections and salaries, choose a solver, encode the objective function and constraints, run the solve, and validate the output against the platform’s actual rules before entering it.
- Assemble the data. You need, at minimum, a current player pool with salary (scraped or exported from the platform) and a projected fantasy-point value per player. Projection quality is the single largest driver of output quality — see the section below on limitations.
- Pick a solver. Google OR-Tools and PuLP (a Python interface to the free CBC solver) are the two most common free choices for a DIY build; both handle MILP natively and are well-documented.
- Encode the objective and constraints. Define the objective function (maximize Σ projected points) and add the constraints from the table above as linear inequalities in the solver’s syntax.
- Run the solve. For a single-sport slate with a few hundred players, a MILP solver returns the optimal lineup in well under a second on ordinary hardware — this is not a computationally expensive step.
- Validate against platform rules. Before submitting, confirm the output actually satisfies the platform’s exact roster rules (FLEX eligibility, team limits) since a subtle constraint-encoding error produces an illegal lineup that looks fine in your code but gets rejected at entry.
For most recreational players, steps 1-3 are more time-consuming than they sound — sourcing clean, current salary and projection data is the actual bottleneck, not the optimization math itself, which off-the-shelf solvers handle in a handful of lines of code.
What Are the Limitations of a Basic Optimizer?
A basic single-lineup MILP optimizer has no built-in concept of ownership, correlation, or outcome variance — it will confidently return the mathematically optimal lineup for whatever projections you feed it, even if those projections are wrong or if the “optimal” lineup is 60% owned and useless for GPP differentiation.
This is the core limitation summarized as garbage in, garbage out: the solver cannot tell the difference between a well-researched projection and a stale one. It also, by default, optimizes for the mean projected outcome — it has no mechanism for understanding that a boom-or-bust player might be preferable in a large-field GPP even at a lower median projection. If you’re building this yourself, closing that gap means adding a simulation loop that models an outcome distribution per player instead of a single point estimate, plus ownership-aware constraints on top of the base MILP — an order of magnitude more engineering than the salary-cap solve above, which is why most DIY builds stop at single-point projections and never get there. Paid tools like SaberSim ship that layer already built. Our comparison of free and paid DFS optimizers covers which off-the-shelf tools already include Monte Carlo simulation and ownership modeling, and at what cost, if building it yourself isn’t worth the engineering time.
Entry fees for real-money DFS contests are at risk with no guaranteed return. If you or someone you know has a gambling problem, call or text the National Problem Gambling Helpline at 1-800-522-4700, or visit our responsible gambling resources.
Should You Build Your Own or Use an Existing Tool?
Building a custom optimizer only makes sense if you need constraints that off-the-shelf tools don’t support — highly specific stacking rules or exposure management across dozens of lineups — or if you’re doing it purely to understand the mechanics. For most players, an existing tool is faster to a usable result.
If you’re weighing that decision, our DFS lineup optimizer comparison reviews the free and paid tools by algorithm, cost, and feature set, including which ones add Monte Carlo simulation and ownership modeling on top of the base MILP solve described above. Before you sink a weekend into a DIY build, run your actual weekly entry volume through the DFS contest EV calculator — if rake already caps your realistic edge at that volume, the hours are better spent on projections than on solver infrastructure you can get for free. And regardless of whether you build or buy, the optimizer only ever answers “what’s the best lineup given these inputs” — it doesn’t replace the contest-selection and bankroll judgment covered in our DFS strategy guide. Track the injury news, weather, and implied-total data that should feed your projection inputs on the Odds Reference dashboard.
Frequently Asked Questions
What kind of math problem is a DFS optimizer solving?
A DFS optimizer solves a Mixed Integer Linear Programming (MILP) problem: maximize total projected fantasy points subject to a salary cap and roster-position constraints, where each player is a binary variable (rostered or not). It’s the same problem class used in logistics and resource-allocation planning, applied to a player pool instead of trucks or warehouses.
Can I build a basic DFS optimizer without being a programmer?
You need at least basic scripting ability. Free solver libraries like Google OR-Tools or PuLP (Python) handle the actual math; your job is formatting the player pool, salary, and constraints correctly and calling the solver. A simple single-lineup optimizer is a manageable weekend project for someone with basic Python experience.
Why do optimized lineups sometimes look wrong?
An optimizer only knows what you tell it. If your projections are stale, miss an injury, or don’t account for a role change, the optimizer will confidently build a lineup around bad inputs — a phenomenon commonly summarized as garbage in, garbage out. The math is never the failure point; the input data almost always is.
Do I need my own optimizer, or should I use an existing tool?
Most players are better served by an existing tool. Building your own only makes sense if you want custom constraints (specific stacking rules, exposure caps across many lineups) that off-the-shelf tools don’t support, or if you’re doing it as a learning exercise. Compare the tradeoffs in our DFS lineup optimizer guide before deciding to build.