In a large Dutch oven or soup pot, melt the butter with the olive oil over medium-low heat.
Add the chopped onion and shallots. Cook for 10–12 minutes, stirring occasionally, until soft and translucent.
Stir in the crushed tomatoes, whole milk, heavy cream, saffron (if using), red pepper flakes, salt, and black pepper.
Bring to a gentle simmer over medium heat, then reduce to low. Simmer uncovered for 25–30 minutes, stirring occasionally.
Add the dry orzo directly to the soup. Continue simmering for approximately 10–12 minutes, stirring frequently, until the orzo is tender.
If the soup becomes too thick, add a splash of milk or broth until you reach your desired consistency.
Taste and adjust the seasoning as needed.
Ladle into bowls and finish with freshly grated Parmesan and parsley.