DeepSeek Now Prices Tokens Like Electricity: 50% Off-Peak Discount and a Spring Boot Pattern to Profit From It
Then define the off-peak window exactly as DeepSeek defines it, in UTC:
@Component public class OffPeakWindow { private static final ZoneId UTC = ZoneId.of("UTC"); public boolean isOffPeak(ZonedDateTime now) { int hour = now.withZoneSameInstant(UTC).getHour(); // Peak: 01:00-04:00 and 06:00-10:00 UTC. Everything else is off-peak. return !((hour >= 1 && hour < 4) || (hour >= 6 && hour < 10)); } }
Now the batch job itself. The cron runs in UTC, so the schedule is stable regardless of where the server lives. 22:00 UTC is 04:00 in Dhaka, deep inside off-peak:
@Component public class NightlyEmbeddingJob { private static final Logger log = LoggerFactory.getLogger(NightlyEmbeddingJob.class); private final OffPeakWindow offPeakWindow; private final ChatClient chatClient; public NightlyEmbeddingJob(OffPeakWindow offPeakWindow, ChatClient chatClient) { this.offPeakWindow = offPeakWindow; this.chatClient = chatClient; } @Scheduled(cron = "${ai.batch.cron}", zone = "UTC") public void runBatch() { if (!offPeakWindow.isOffPeak(ZonedDateTime.now())) { log.warn("Skipping batch run: peak hours in UTC"); return; } // Heavy work: embeddings, summarization, eval runs. } }
ai.batch.cron=0 0 22 * * *
The window check is a safety net, not the primary control. The cron is the primary control, and the check exists for the day someone changes the cron to 08:00 UTC and forgets what that costs. Defensive, cheap, and it turns a pricing policy into code.
The second piece is an estimator, because a cost problem you cannot see is a cost problem you will not fix. Model the official table as data:
public record TokenPrice(double inputPerM, double outputPerM, double cacheHitPerM) {} public final class DeepSeekRates { public static final TokenPrice FLASH_OFF_PEAK = new TokenPrice(0.22, 0.66, 0.007); public static final TokenPrice FLASH_PEAK = new TokenPrice(0.44, 1.32, 0.014); public static final TokenPrice PRO_OFF_PEAK = new TokenPrice(0.66, 1.98, 0.022); public static final TokenPrice PRO_PEAK = new TokenPrice(1.32, 3.96, 0.044); private DeepSeekRates() { } }
Then a component that picks the right tier by hour and logs an estimate after every call:
@Component public class CostTracker { private final OffPeakWindow offPeakWindow; public CostTracker(OffPeakWindow offPeakWindow) { this.offPeakWindow = offPeakWindow; } public void track(String model, TokenPrice peak, TokenPrice offPeak, long cacheHitTokens, long inputTokens, long outputTokens) { boolean offPeak = offPeakWindow.isOffPeak(ZonedDateTime.now()); TokenPrice price = offPeak ? offPeak : peak; double cost = (cacheHitTokens / 1_000_000.0) * price.cacheHitPerM() + (inputTokens / 1_000_000.0) * price.inputPerM() + (outputTokens / 1_000_000.0) * price.outputPerM(); log.info("{} {} cost estimate: ${} (tokens: {} cache hit / {} input / {} output)", model, offPeak ? "off-peak" : "peak", cost, cacheHitTokens, inputTokens, outputTokens); } }
Wire track(...) wherever you call the model, and after a week you have a distribution: what your workload costs at each hour. That distribution is the thing to optimize, because the off-peak discount only helps the workloads you actually move.
The checklist before you run a bill through it
- Move the cron-able work first. Embeddings, nightly evals, digest generation. These are pure savings: same output, half the price.
- Instrument cache-hit ratio. If 80% of your input tokens are cache hits, the new cache-hit price is your real price. Log it per request and per session.
- Set the window in UTC, not server-local time. A server in Dhaka and a server in Frankfurt must agree on what “off-peak” means.
zone = "UTC"on@Scheduledkeeps the schedule honest. - Re-check OpenRouter and other resellers. DeepSeek’s first-party pricing changed, but the same open-weight models are still sold by other providers at older rates. A one-line base-URL change in Spring AI is your cheapest mitigation.
- Re-run your cost estimates after August 16. The old flat-rate math is dead. If your spreadsheets still say $0.435 for V4 Pro input, they are wrong twice: the price moved, and it now depends on the hour.
What I would do differently
The lesson here is not “DeepSeek raised prices.” Every frontier provider will eventually do time-of-day or tiered pricing, because demand is diurnal and infrastructure is expensive to idle. The lesson is that model cost stopped being a constant, and my code was written as if it was.
I have been building production AI systems with Spring Boot and Spring AI for over a year, and the first time I integrated a frontier model I hardcoded a price per million tokens in a constants file. That file is now a time function. The fix is not cleverer math, it is treating pricing like configuration: a table, a UTC clock, and a log line that makes the cost visible per call. When the next provider copies DeepSeek’s playbook, you change the table, not the architecture.
Have you checked what your DeepSeek bill would look like under the new peak and off-peak rates? What workload are you planning to move into the off-peak window? I read every response.
I write about Java, Spring Boot, and AI every week. Subscribe, it’s free.
Bookmark this one. The next time a model provider announces a discount, your first question should not be “how much off?” It should be “off what baseline, and at what hour?”
Fuente: Artículo original