On 30 July in zone 6b there are 83 days until the first frost. Asked what you could plant into that, the first version of our planting filter said go ahead on 122 of 151 crops, apple and asparagus among them. Nothing errored. Three fixes later it says 59, and every answer it gives now moves when the planting date does.
The question
It is the end of July. The bed where the garlic came out is bare, you have an hour and no plan, and the only thing you need to know is whether anything you put in today will give you something before the cold ends it.
The request that started this was typed at the end of July and has not been cleaned up: "I actually do want to plant something but its almost august, is it too late?" We already had the arithmetic for it. That turned out to be the problem.
What you do without an app
You find the days-to-maturity number on the seed packet, you find your first frost date, and you count backwards. If the sum clears, you plant.
It is a good method and it has a hole in it. That number does not always start counting from the same place. Of our 151 crops, 110 record a days-to-maturity figure, and of those 47 count from the day the seed goes in and 63 count from the day the plant goes out. A tomato's 52 to 90 days is measured from transplant. It quietly leaves out six to eight weeks on a windowsill and another week or two of waiting after the last frost. The packet prints one number and does not tell you which starting line it used.
The other 41 crops record no figure at all.
Then there is the second hole, which is worse. Days to maturity tells you when a plant is finished. It does not tell you when it starts paying you. A bush bean gives you beans for a month. Counting to the end of that month and comparing it against your frost date will talk you out of a crop you would have got.
The first answer: 122 of 151
We already had an engine that decides whether a planting will beat the frost. It was built for someone who has already planted, and it works. Give it a pepper started on 29 July and it tells you the harvest opens on the wrong side of the frost. That engine exists because the app used to hold exactly that arithmetic and show a cheerful countdown to germination instead.
"What can I plant today" is the same arithmetic run forwards. So the first version just ran it forwards.
Zone 6b, 30 July. Last spring frost 17 April, first fall frost 21 October, which leaves 83 days. The engine came back with plant it now on 122 of 151 crops.
One word before the table, because the whole post turns on it. Margin is the gap between the day a crop starts giving you something and the day of your first frost. Big margin, plant it. Small margin, gamble. Negative, do not bother.
| Crop | Verdict | Days of slack it claimed |
|---|---|---|
| Apple | Plant it now | 97 |
| Apricot | Plant it now | 127 |
| Asparagus | Plant it now | 187 |
Our catalog holds 53 perennials. Forty-nine of them said go.
Here is why, and it is not a coding slip. A perennial's growth stages in our data describe an established plant's year: bud break, bloom, fruit, dormancy. Those hang off the frost dates, because a mature tree's year genuinely does. Ask when an apple ripens and the honest answer is "late summer, every year." Ask whether to plant one today and that first answer is still sitting there. Still true. About a completely different tree.
The fix is one field. If the crop is a perennial, do not answer the frost question at all — say it is a perennial and give the planting window instead. Tender perennials are left out of that rule on purpose. A pepper is a perennial in its native range and an annual in Ohio, and it does crop in its first year.
The tomato that ripened six weeks before it was sown
That took the list from 122 to 73. Sorting what was left by how much slack it claimed put a tomato near the top with 125 days to spare, on a seed sown that morning.
Our tomato record holds no direct-sow figure: no number of days either side of the last frost when you would put a tomato seed straight in the ground. Nobody direct-sows tomatoes in a temperate garden, so no extension service publishes it and we never sourced one. When the engine tried to place the ripening stage against a sow date, it had nothing to hang it on, so it fell back to the crop's ordinary calendar. Started indoors in March. Out a week after the last frost. Ripening from 18 June.
18 June is 42 days before the seed went in the ground.
The engine was not confused about tomatoes. It knew exactly when a normal tomato ripens and it said so, accurately, while being asked about a different one. The 125 days is real arithmetic: 21 October minus 18 June.
The fix is a refusal. Only answer for the ways of planting a crop actually records. Tomato now gets the buy-a-start answer and nothing else, which on 30 July comes out at 28 days of margin. That one is a real answer.
187 days of margin against a frost 83 days away
Parsley survived both fixes. It is a biennial rather than a perennial, and it records both ways of planting, so neither of the first two fixes had anything to say about it. It reported 187 days of margin.
There were 83 days left in the season.
187 is not a number that is slightly too big. 17 April to 21 October is 187 days. That is the whole frost-free season in zone 6b, start to finish, handed back with the word "margin" next to it. Nine crops came out at exactly that figure on the first run: anise hyssop, asparagus, bee balm, catnip, lemon balm, mint, parsley, rhubarb and sage. The perennial fix took eight of them. Parsley walked through.
Here is the mechanism. Ask about a parsley plant bought as a start, and its harvest window is recorded against the frost dates rather than against the day the plant goes in. So the engine put the harvest as opening on 17 April, and 17 April does not move whatever date you hand it. Same shape as the apple tree, one layer down. It had just watched two fixes go past without being touched.
Every one of those answers would have got past you too. 187 is only obviously wrong once you already know there are 83.
The third fix is the general one, and it is three lines. Ask the same question again for a planting thirty days later. If the harvest window does not move, then this crop's calendar is not a function of when you plant it, and the honest output is that we cannot answer — not a number.
The check nobody had written down
Of the 122 answers the first version gave, 60 claimed more days of margin than there were days left in the season. That is not a subtle test. It needs one subtraction and no knowledge of gardening at all. It was not in the suite, because every test we had asked whether one crop behaved correctly, and none of them asked whether the list as a whole added up.
The engine suite now runs 64 tests. Three of them are about this:
- No perennial ever says "plant it now."
- No margin is larger than the number of days left before the frost.
- Every surviving verdict changes when the planting date changes.
The third is the one worth stealing. All three bugs fail it, including the two we had not found yet when it was written. An answer about today that is identical to the answer about a month from today was never an answer about today.
The other thing that would have worked is not a test. Run the thing across everything you have and look at the ends of the list — the top, the bottom, and anything whose size is impossible. Both remaining bugs were sitting in the first three rows of a sorted list.
What it says now
Same day, same zone, same 151 crops:
| Answer | Crops | What is in there |
|---|---|---|
| Plant these now | 59 | Basil with 69 days to spare, radish 62, spinach 55, kale 43, bush beans 38 |
| Only just | 9 | Pumpkin, winter squash, celery and brussels sprouts, on 3 to 13 days |
| Not this year | 12 | Potato, sweet potato, sunflower, sorghum |
| A different question | 53 | The perennials, given their planting window instead of a verdict |
| No harvest window recorded | 13 | Mostly ornamentals |
| We cannot say | 5 | Named, each with the reason |
None of that is a list anybody wrote for late July. Run the same filter on 20 May and 79 crops say go. Run it on 12 October and none do, while 80 say not this year. Run it on 15 January and 94 crops tell you their planting window has not opened yet, which is the correct and slightly deflating answer.
In the app it is one line of text under the search box on the add-a-plant screen, closed by default, because most people arrive already knowing what is in their hand. Each row is the crop, and the number of days it has to spare or falls short by. The number is the point. "Pumpkin: only just" is a shrug; "pumpkin: 3 days to spare" is a decision.
Where we are still wrong
Garlic gets the worst answer on the page. Our data records it as a perennial and it carries no planting offsets at all, so the filter drops it in with the perennials and shows "next year." Garlic goes in around October. The true answer on 30 July is a date in October, and instead we hand back the two words most likely to talk somebody out of it.
Five crops get "we cannot say," and one of them is cucumber. Cereal rye, hairy vetch, onion and shallot are the others. Cucumber's record holds a figure for starting it indoors and a figure for how long it takes to come up, and no planting offset the engine can hang a harvest on, so it refuses. Refusing is the right behavior and the wrong outcome. That is a data gap wearing a feature's clothes.
Summer squash comes back as "no harvest window recorded," filed with the marigolds. It does have one. Its harvest stage is measured from the day you sow the seed, and the only planting date the crop records is a transplant date — two weeks after the last frost. The stage and the timing disagree about which starting line they use, so the engine cannot place the harvest and correctly declines to guess. It is the same disagreement this post opened with, one layer down and inside our own data. Nobody spotted it until the filter made every crop we hold stand in the same line.
There is no fall-crop rule. A brassica sown now for an October cutting wants the frost as a finish line, not a deadline, because a light frost sweetens it. Our filter has no sourced fall window, so it treats any harvest landing past the first frost as "not this year." That is pessimistic on purpose. Inventing the fall window would produce confident nonsense across a third of the catalog, and confident nonsense is what this entire post is about.
And all of it hangs off one number: your first fall frost date, which is a fifty-fifty average and not a promise.
One more, and it is about this post rather than about the app. None of the three broken versions was ever saved into our version history. The code that answers this question appears there exactly once, already fixed. So checking the figures above meant rebuilding the first version from our own written-up account of the bug and running it again.
Which is how we found that the account had the tomato ripening in September. The run that produced the 125-day figure had it ripening on 18 June. September is the plausible-sounding month, June is what the machine actually said, and the plausible one is what got written down. It is corrected now. That is twice in two posts that fact-checking a failure story turned up a second failure inside it, and we are going to keep publishing those too.
The frost-date lookup the whole thing runs on is free, no signup.
The app it lives in is in beta now. Join the beta if you want it. What else shipped this week is on the updates page.