Computational Meatballs

A couple of years ago, I worked through the wonderful Computational Thinking MIT course. In the spirit of that class, I put together a (quite goofy) Pluto notebook yesterday to resolve a question that I had.

I was preparing a meal of spaghetti and meatballs and, after forming all of my meatballs, was disappointed to learn that they would not all fit in my sauté pan. This meant that I would have to brown my meatballs in two batches, taking more time. I wondered: Can I fit more of the meatball mix in the pan by forming a large number of small meatballs, or is it better to make a smaller number of large meatballs? Once I finally had all of my browned meatballs simmering in the sauce, I took the time to figure it out…

The parameters were as follows:

  • My pan is 10 inches in diameter
  • The minimum meatball size I am willing to accept is 1 inch in diameter
  • The maximum meatball size I am willing to accept is 3 inches in diameter

It turns out that a smaller number of large meatballs results in the largest volume of meatball mix fitting in the pan. In my case, seven 2.8 inch meatballs is the optimal solution :smile:

Here’s a .gif of the notebook in action:

computational meatballs


The world does not know this yet, but this needs to be an app. :laughing:


In case you want to find your own optimal meatball size, here are the contents of the Pluto cells:

using Plots
using PlutoUI

radius_min = 0.5
radius_max = 1.5
pan_radius = 5

function circle_shape(h, k, r)
	θ = LinRange(0, 2 * π, 500)
	h .+ r * sin.(θ), k .+ r * cos.(θ)

@bind r Slider(radius_min:0.1:radius_max; show_value=true)

R = pan_radius
D = sqrt(3) * r # hexagon diameter

grid = [
	(iseven(i) ? x + r : x, y) for x in -R:2*r:R, # offset for hexagonal lattice
	(i, y) in enumerate(-R:D:R)

in_pan(pair) = sqrt(pair[1]^2 + pair[2]^2) + r ≤ R # check to see if the meatball is contained in the pan
num_meatballs = count(pair -> in_pan(pair), grid)
total_volume(N, r) = (4/3 * π * r^3) * N
V = total_volume(num_meatballs, r)
total_weight(V) = (V * 16.387) / 453.592 # assumes density of 1 gram per cubic centimeter, 1 cubic inch ≈ 16.387cm³, approx 453.592 grams per pound
p = plot(
	title="size = $(r*2) in / num_meatballs = $(num_meatballs) / weight = $(round(total_weight(V), digits=1)) lbs"

for pair in grid
	if in_pan(pair)
			circle_shape(pair[1], pair[2], r),


Are you sure that the larger meatballs are actually quicker to brown than two batches of smaller meatballs? A large meatball will only have a small patch in contact with the pan, and will thus require many more reorientations in order to brown the entire surface.

A larger number of smaller meatballs will have a larger total contact area with the pan, thus producing more browning at any one time.

An additional and unfortunate drawback with increased size is the overall smaller surface-to-volume ratio, reducing the overall browning :confused: This fact also has to be factored into the time-to-brown discussion above.


I think this is a fair point. Maybe version 2.0 can include multi-objective optimization. :laughing:


We need some heavy duty modelling here
Maillard reaction - Wikipedia


I was actually more referring to the fact that less overall required browning has an effect on how long time it takes to perform the job. The effect that the amount of browning has on the taste, however, would be another (important) objective to consider :wink:


Now to find what the effect is if you are willing to make two different sizes of meatball. How many of each size?

1 Like

I like the taste of the browned parts so much that I make “meatballs” flat, more like hamburger patty, but around 2–4cm in diameter (does not really matter, as they are more or less the same width, also I don’t bother to make them too regular). I use a largish saute pan, 28cm.

But I think the limiting factor is the power of my induction stovetop, the Maillard reaction is endothermic at normal frying temperatures. As Julia Child often said, don’t crowd the pan!


:smile: This is true, but there are fewer of them, so I wonder if the total number of reorientations for all meatballs in the pan is actually greater than the number required for the larger number of smaller meatballs?

We need someone who knows something about contact mechanics to tell us how we can calculate the area of the meatball that is in contact with the pan, given its mass and elasticity. Then, we could figure out exactly how many rotations are needed to brown the entire surface for different sizes :thinking:

Mine always come out with somewhat flat sides anyways where they are deformed from being in contact with the flat surface of the pan. Maybe I will try your meatdiscs next time around…