
Soto Betawi (Jakarta Beef & Coconut Milk Soup)
Tender beef simmered in a fragrant broth of lemongrass and galangal, then enriched with coconut milk and milk until silky, with potatoes, tomatoes and a shower of fried shallots. This is Jakarta's most comforting bowl of soup.
Servings
Ingredients
Nutrition
Per serving
Steps

Simmer the beef
Put the beef in a large pot with the water, lemongrass, , kaffir lime leaves and bay leaves. Bring to a boil, then skim off the grey foam that rises to the top so the broth stays clear. Lower the heat and simmer gently, covered, for 1½–2 hours, until the beef is fork-tender.
- 800 g beef
- 2 litres water
- 2 lemongrass stalks
- 4 cm piece
- 4 kaffir lime leaves
- 2 bay leaves
✅ Done when: a fork slides easily into the beef and the broth tastes rich

Make the spice paste
While the beef simmers, blend the shallots, garlic, candlenuts, coriander seeds, nutmeg and white pepper with a splash of water into a smooth paste. Heat the oil in a small pan and cook the paste on low heat for 5–6 minutes, stirring often, until it turns a shade darker and smells fragrant instead of raw. This step matters: candlenuts must be fully cooked, never left raw.
- 6 shallots
- 4 garlic cloves
- 4 candlenuts
- 1 tsp coriander seeds
- 1/2 tsp ground nutmeg
- 1 tsp white pepper
- 2 tbsp vegetable oil
✅ Done when: the paste darkens slightly and no longer smells raw

Add paste and potatoes
Lift the beef out of the broth and set it aside on a plate. Strain the broth if you want a clearer soup, then return it to the pot. Stir in the fried spice paste and the potatoes, and simmer gently, uncovered, for 12–15 minutes, until the potatoes are nearly tender.
- 2 potatoes
✅ Done when: a knife slides into the potatoes with just a little resistance

Add tomatoes and coconut milk
Add the tomatoes, coconut milk, milk, salt and sugar. Simmer on low heat for about 10 minutes, stirring now and then. Keep the heat gentle and do not let it come to a hard boil, or the coconut milk can split and look grainy.
- 2 tomatoes
- 400 ml coconut milk
- 250 ml whole milk
- 1 tsp salt
- 1 tsp sugar
✅ Done when: the broth looks creamy and pale, and the potatoes are fully tender

Return the beef
Cut the cooked beef into bite-sized pieces, or shred it, then return it to the pot. Warm through gently for 2–3 minutes and taste, adding a little more salt if needed.
- 800 g beef (cut, from step 1)
✅ Done when: the beef is heated through and the soup tastes well seasoned

Serve
Ladle the soup into bowls. Top with fried shallots, scallions and celery leaves, and serve with lime wedges, sweet soy sauce and sambal on the side.
- 2 limes
- 3 tbsp fried shallots
- 2 scallions
- small handful celery leaves
- to serve and sambal

Simmer the beef
Put the beef in a large pot with the water, lemongrass, , kaffir lime leaves and bay leaves. Bring to a boil, then skim off the grey foam that rises to the top so the broth stays clear. Lower the heat and simmer gently, covered, for 1½–2 hours, until the beef is fork-tender.
- 800 g beef
- 2 litres water
- 2 lemongrass stalks
- 4 cm piece
- 4 kaffir lime leaves
- 2 bay leaves
✅ Done when: a fork slides easily into the beef and the broth tastes rich

Make the spice paste
While the beef simmers, blend the shallots, garlic, candlenuts, coriander seeds, nutmeg and white pepper with a splash of water into a smooth paste. Heat the oil in a small pan and cook the paste on low heat for 5–6 minutes, stirring often, until it turns a shade darker and smells fragrant instead of raw. This step matters: candlenuts must be fully cooked, never left raw.
- 6 shallots
- 4 garlic cloves
- 4 candlenuts
- 1 tsp coriander seeds
- 1/2 tsp ground nutmeg
- 1 tsp white pepper
- 2 tbsp vegetable oil
✅ Done when: the paste darkens slightly and no longer smells raw

Add paste and potatoes
Lift the beef out of the broth and set it aside on a plate. Strain the broth if you want a clearer soup, then return it to the pot. Stir in the fried spice paste and the potatoes, and simmer gently, uncovered, for 12–15 minutes, until the potatoes are nearly tender.
- 2 potatoes
✅ Done when: a knife slides into the potatoes with just a little resistance

Add tomatoes and coconut milk
Add the tomatoes, coconut milk, milk, salt and sugar. Simmer on low heat for about 10 minutes, stirring now and then. Keep the heat gentle and do not let it come to a hard boil, or the coconut milk can split and look grainy.
- 2 tomatoes
- 400 ml coconut milk
- 250 ml whole milk
- 1 tsp salt
- 1 tsp sugar
✅ Done when: the broth looks creamy and pale, and the potatoes are fully tender

Return the beef
Cut the cooked beef into bite-sized pieces, or shred it, then return it to the pot. Warm through gently for 2–3 minutes and taste, adding a little more salt if needed.
- 800 g beef (cut, from step 1)
✅ Done when: the beef is heated through and the soup tastes well seasoned

Serve
Ladle the soup into bowls. Top with fried shallots, scallions and celery leaves, and serve with lime wedges, sweet soy sauce and sambal on the side.
- 2 limes
- 3 tbsp fried shallots
- 2 scallions
- small handful celery leaves
- to serve and sambal
The Story Behind the Dish
Soto Betawi takes its name from the Betawi, the native people of Jakarta, and belongs to the huge family of Indonesian sotos, each region's own version of soup. What sets it apart is the broth: instead of the clear, turmeric-tinted liquid used elsewhere, Jakarta's street vendors enriched theirs with coconut milk and dairy milk, giving it a pale, almost creamy richness unusual in Indonesian cooking.
It became a fixture of Jakarta's food stalls and warungs in the second half of the 1900s, often made with offal as well as beef, and is now one of the city's signature dishes, eaten at any time of day.
⭐ Why It's Famous
It is prized for its rich, creamy broth, a rare combination of coconut milk and dairy milk, that makes it feel more indulgent than most Indonesian soups.
💡 Fun Fact
Many Jakarta soto Betawi stalls simmer beef organs like tripe and lung alongside the meat, so the soup can be ordered 'campur' (mixed) for those who want the full traditional experience.
Jakarta
-6.21°S, 106.85°E
Related recipes
Comments (0)
No comments yet. Be the first to share your thoughts!


