March 16, 2020
The Land of Hand-Pulled Noodles
Article-Lanzhou-Noodle-School-China

In Lanzhou, a sprawling city in northwest China, a bowl of fresh, chile-slicked noodles is never more than a couple bucks away.

I sometimes impetuously book trips thousands of miles away solely to taste a dish. A taste of khinkali and khachapuri has sent me to Tbilisi. Shawarma to Beirut. Samsa to Tashkent. Lagman to Kashgar. And it was a bowl of noodles in the Chinese enclave of the San Gabriel Valley in Los Angeles that convinced me to fly to Lanzhou, China, several months ago.

Most Chinese people haven’t been to Lanzhou and will likely never go. But many people, Chinese and citizens around the globe, know about its existence for precisely one reason: they’ve eaten a bowl of the city’s signature beef noodle soup. The hand-pulled beef noodles of Lanzhou (the capital of Gansu province in Northwest China) may look, at first glance, like any other bowl of chewy noodles bobbing in a clear broth, but many of the dish’s subtle details are invisible to the naked eye.

Lanzhou Beef Noodles

The wheat-based dough requires a mind-numbing 900 kneads before noodles can be pulled from it. Ten or more ingredients go into the aromatic, bright red chile oil that slicks the surface of the soup. The broth is made using more than 15 spices (including star anise, cumin, white cardamom, nutmeg, and dried ginger) and a tangle of cow, yak, and chicken bones, boiled for at least 15 hours. The bones and spices meld into a deep, nuanced broth that tastes neither Chinese nor Central Asian—a result of being influenced and revised by the many hands and palates of travelers passing through the Silk Road. The broth reminds me of Vietnam’s aromatic beef pho, minus the fish sauce. And when it’s all said and done, an order is assembled in two minutes or less.

Months after that bowl in LA, I awoke to the loud thump of the airplane wheels touching down on Gansu soil. The province’s neon-lit capital, Lanzhou, is home to more than a thousand noodle shops. Walking through the city of 3 million people, a bowl of Lanzhou beef noodles (costing the equivalent of $1.50) is never far away. The best shops open as early as 6 a.m. and usually sell out of noodles before noon.

Lanzhou Beef Noodles

Lanzhou beef noodles were originally a variation of a curry-based noodle soup from Henan province traced to the 1800s. Toward the end of the Qing dynasty in the early 1900s, a man named Chen Wei Jing from Bo’ai county in Henan brought the noodle soup to Lanzhou, where it continued to be sold widely and innovated upon. In 1919, Ma Bao Zi, the Hui Chinese man considered to be the godfather of Lanzhou beef noodles, opened up the first brick-and-mortar beef noodle soup shop in Lanzhou, setting off an explosion of noodle shops, vocational noodle schools, and employment opportunities for people all over China.

Ask most people about the soup’s draw, and eight out of ten diners will mention texture. Part of the noodles’ trademark chew comes from the ash of a specific plant found only in nearby deserts like the Gobi, just north of Gansu province. Known in Chinese as peng hui cao and in English as Aral barilla, halogeton, and saltlover, the mystical plant is burned into a gray ash and serves as potassium carbonate, which, when mixed with wheat flour, becomes the alkaline ingredient. Without gray peng hui cao, noodles would lack elasticity and that characteristic yellow coloring caused by rising pH levels that occur when wheat and alkaline react together chemically.

Lanzhou Beef Noodles

At 9 a.m. on our second day in Lanzhou, my wife and I walked into one of the city’s most popular beef noodle restaurants, Wu Mu Lei, packed with locals, young and old, awaiting their morning dosage. People paid for vouchers—each one entitling them to a bowl—while others slurped noodles loudly at tables. A long queue formed while cooks yelled out orders. We immediately understood the system and headed to the ticket booth. The large vats of boiling water—think bubbling Jacuzzis—turned the entire room into a sauna. The cooks were of Hui Chinese Muslim descent and all wore white tajiya, traditional Muslim skull caps. The role of each cook was carefully defined, like a five-piece rock band.

One man sounded off orders and passed finished bowls to patrons. Two men next to him kneaded massive mounds of dough rapidly with their hands, forearms, and elbows, exhaustively sinking all of their body weight with each plunge like they were performing CPR resuscitation. They then ripped out burrito-size portions from the mother dough and lined them up in a row directly in front of a third cook, who was the most senior and skilled in the kitchen.

Lanzhou Beef Noodles

In a 15-second fit of stretching, twisting, and slapping motions mixed with gravity and momentum, this cook could convert a bar of dough into the patron’s desired style of noodles–however thin, however wide. He then tossed the freshly strewn strands of noodles into a rolling vat of hot water, where a fourth cook fished the cooked noodles out with a long pair of cooking chopsticks and into a bowl. The fifth and final cook added in the golden beef broth and boiled radish, topping off the noodles with the powerful broth, a handful of cilantro and garlic chives, and a splash of bright red, lip-numbing chile oil.

Punctuating this focused process, we heard orders for specific noodle shapes being fired off:

“Number-two thin, number-three thin, chive, number-two wide, number-one thin, big wide, double pillar!”

In relation to Italian pasta shapes, this more or less translates to: “Thin spaghetti, thinner spaghetti, tagliatelle, thin and wide pappardelle, angel hair, big pappardelle, big pici!” But a pasta machine is incapable of churning out seven different sizes and shapes of pasta within a few minutes. And when this five-piece band of cooks is really in sync, the soup will be passed on to you in under two minutes.

I ordered number-two thin, the most popular style, because of the noodle’s delectable, slippery texture and fast cooking time. My wife ordered the chive for a wider, more toothsome texture. Two minutes later, we received our tray of freshly composed bowls of beef noodles and ended up sharing a table with an elderly couple from Lanzhou.

I fetched out some chopsticks and immediately began searching for a soup spoon. The couple laughed, sensing that we weren’t from there, and explained the process. “In Lanzhou, we don’t use soup spoons,” he said. He explained that Lanzhou has always been poor and that some restaurants, until recently, couldn’t even afford to provide furniture. There were times one would have to crouch outside and eat the noodles with chopsticks only.

At each noodle shop I visited, I arrived as a diner and walked out a student. As our meal at Wu Mu Lei drew to a close, the older man next to us grabbed his near-finished bowl with both hands. Like Moses parting the Red Sea, he blew a little bit of air onto the surface of the broth, nudging the pool of chile oil to the side and revealing an open patch of clean broth. He took a few sips and smiled at us, nodding for us to try. This is how you sip from the Silk Road. And this is why I flew six thousand miles to Lanzhou for a bowl of noodles.

Wu Mu Lei Peng Hui Beef Noodles
(吾穆勒蓬灰牛肉面)
2168 Bei Bin He Zhong Lu, Lanzhou
(七里河区, 北滨河西路 2168号)

Dylan James Ho

Dylan James Ho is photographer and writer from Los Angeles. He and his wife Jeni Afuso are also behind the husband-wife-photo duo, DYLAN + JENI. When they aren’t photographing food, cocktails and hotels, they enjoy traveling far and away to unearth some of the world’s most delicious food. They have contributed to Bon Appetit, Food & Wine, Saveur, AFAR, Travel + Leisure, Garden & Gun, GQ, Mr. Porter and PUNCH and have photographed numerous food and cocktail books.

[email_signup id="3"]
<div class="email-subscribe exp-subscribe subscribe"> <div class="alert alert-success exp-success ga-etembed-success" style="display:none;"> Great! You've signed up successfully! </div> <div class="alert alert-danger exp-error" style="display:none;"> We are experiencing an error, please try again. </div> <form name="subscribe" id="email-signup" class="email-signup-form" action="https://www.tastecooking.com/wp-admin/admin-ajax.php" method="POST" target="_top" data-event-assigned="false"> <fieldset class="form-group form-inline email-submit-group"> <label for="email-address" class="sr-only">Email Address</label> <input id="email-newsletter" type="email" placeholder="your@email.com" class="email-newsletter text email form-control" name="email" value=""> <button type="submit" value="Subscribe" name="subscribe" class="btn btn-primary email-submit-btn ga-etembed-success"> <i class="fa fa-envelope"></i> Subscribe </button> </fieldset> <small class="exp-small terms" style=""> By clicking Subscribe, I acknowledge that I have read and agree to the Penguin Random House <a href="http://www.penguinrandomhouse.com/privacy/" target="_blank">Privacy Policy</a> and <a href="http://www.penguinrandomhouse.com/terms/" target="_blank">Terms of Use</a> and agree to receive news and updates from TASTE and Penguin Random House. </small> <fieldset class="field-group checkboxes" style="display:none"> <div class="checkbox"> <label> <input type="checkbox" name="programs[]" value="505,50501,1" class="exp-checkbox" checked="checked"> <span><strong>Tastebook General</strong></span> </label> </div> <div class="checkbox"> <label> <input type="checkbox" name="programs[]" value="505,50502,1" class="exp-checkbox" checked="checked"> <span><strong>Tastebook Promo</strong></span> </label> </div> </fieldset><!-- /.checkboxes --> <input type="hidden" name="data_acq_code" value="TASTE_POPUP_STATIC_ONGOING" /> <input type="hidden" name="data_programs" value="50501|505,50502|505" /> <input type="hidden" name="form_id" value="3" /> <input type="hidden" name="partner" value="" /> <input type="hidden" name="action" value="crown_email_signup_submit" /> <input type="hidden" name="ref_url" value="" /> </form> </div> <script> jQuery(document).ready(function () { var unassigned_forms; setInterval( function() { //Check for unassigned forms var forms = jQuery( '.email-signup-form' ); unassigned_forms = false; forms.each( function( index ) { if ( jQuery( this ).attr( 'data-event-assigned' ) === 'false' ) { unassigned_forms = true; } }); if ( unassigned_forms ) { forms.off( 'submit' ).on( 'submit', function ( e ) { forms.attr( 'data-event-assigned', 'true' ); e.preventDefault(); // Basic email validation var email = jQuery(e.target).find('.email-newsletter').val(), valid_email = false, groupEl = jQuery(e.target).closest('.email-subscribe'); if ( !!email && typeof(email) === "string" ) { var email_array = email.split('@'); if ( email_array.length === 2 ) { if ( email_array[1].split('.').length > 1 ) { valid_email = true; } } } if ( valid_email ) { jQuery('.alert-danger').hide(); // Show loading gif groupEl.find('.email-signup-form').hide(); groupEl.find('.email-submit-loading').show(); // Populate ref_url jQuery(this).find('input[name="ref_url"]').val(window.location.href); // Generate Payload var payload = jQuery(this).serializeArray(); jQuery.ajax({ url: jQuery(this).attr('action'), type: 'POST', data: payload, success: function (data) { // Hide loading spinner groupEl.find('.email-signup-form').show(); groupEl.find('.email-submit-loading').hide(); // Display success msg var target = jQuery(e.target); jQuery(e.target).hide(); jQuery(e.target).parent().find('.alert-success').show(); jQuery(e.target).parent().find('#downloadbtn').show(); }, fail: function (err) { // Hide loading spinner groupEl.find('.email-signup-form').show(); groupEl.find('.email-submit-loading').hide(); // Display failure msg var target = jQuery(e.target); jQuery(e.target).hide(); jQuery(e.target).parent().find('.alert-danger').show(); } }); } else { groupEl.find('.alert-danger').html('Please enter a valid email address.').show(); } }); forms.off( 'keypress' ).on( 'keypress', function ( e ) { if ( e.which === 13 ) { e.preventDefault(); jQuery( this ).submit(); } }); } }, 100); }); </script>
[email_signup id="3"]
<div class="email-subscribe exp-subscribe subscribe"> <div class="alert alert-success exp-success ga-etembed-success" style="display:none;"> Great! You've signed up successfully! </div> <div class="alert alert-danger exp-error" style="display:none;"> We are experiencing an error, please try again. </div> <form name="subscribe" id="email-signup" class="email-signup-form" action="https://www.tastecooking.com/wp-admin/admin-ajax.php" method="POST" target="_top" data-event-assigned="false"> <fieldset class="form-group form-inline email-submit-group"> <label for="email-address" class="sr-only">Email Address</label> <input id="email-newsletter" type="email" placeholder="your@email.com" class="email-newsletter text email form-control" name="email" value=""> <button type="submit" value="Subscribe" name="subscribe" class="btn btn-primary email-submit-btn ga-etembed-success"> <i class="fa fa-envelope"></i> Subscribe </button> </fieldset> <small class="exp-small terms" style=""> By clicking Subscribe, I acknowledge that I have read and agree to the Penguin Random House <a href="http://www.penguinrandomhouse.com/privacy/" target="_blank">Privacy Policy</a> and <a href="http://www.penguinrandomhouse.com/terms/" target="_blank">Terms of Use</a> and agree to receive news and updates from TASTE and Penguin Random House. </small> <fieldset class="field-group checkboxes" style="display:none"> <div class="checkbox"> <label> <input type="checkbox" name="programs[]" value="505,50501,1" class="exp-checkbox" checked="checked"> <span><strong>Tastebook General</strong></span> </label> </div> <div class="checkbox"> <label> <input type="checkbox" name="programs[]" value="505,50502,1" class="exp-checkbox" checked="checked"> <span><strong>Tastebook Promo</strong></span> </label> </div> </fieldset><!-- /.checkboxes --> <input type="hidden" name="data_acq_code" value="TASTE_POPUP_STATIC_ONGOING" /> <input type="hidden" name="data_programs" value="50501|505,50502|505" /> <input type="hidden" name="form_id" value="3" /> <input type="hidden" name="partner" value="" /> <input type="hidden" name="action" value="crown_email_signup_submit" /> <input type="hidden" name="ref_url" value="" /> </form> </div> <script> jQuery(document).ready(function () { var unassigned_forms; setInterval( function() { //Check for unassigned forms var forms = jQuery( '.email-signup-form' ); unassigned_forms = false; forms.each( function( index ) { if ( jQuery( this ).attr( 'data-event-assigned' ) === 'false' ) { unassigned_forms = true; } }); if ( unassigned_forms ) { forms.off( 'submit' ).on( 'submit', function ( e ) { forms.attr( 'data-event-assigned', 'true' ); e.preventDefault(); // Basic email validation var email = jQuery(e.target).find('.email-newsletter').val(), valid_email = false, groupEl = jQuery(e.target).closest('.email-subscribe'); if ( !!email && typeof(email) === "string" ) { var email_array = email.split('@'); if ( email_array.length === 2 ) { if ( email_array[1].split('.').length > 1 ) { valid_email = true; } } } if ( valid_email ) { jQuery('.alert-danger').hide(); // Show loading gif groupEl.find('.email-signup-form').hide(); groupEl.find('.email-submit-loading').show(); // Populate ref_url jQuery(this).find('input[name="ref_url"]').val(window.location.href); // Generate Payload var payload = jQuery(this).serializeArray(); jQuery.ajax({ url: jQuery(this).attr('action'), type: 'POST', data: payload, success: function (data) { // Hide loading spinner groupEl.find('.email-signup-form').show(); groupEl.find('.email-submit-loading').hide(); // Display success msg var target = jQuery(e.target); jQuery(e.target).hide(); jQuery(e.target).parent().find('.alert-success').show(); jQuery(e.target).parent().find('#downloadbtn').show(); }, fail: function (err) { // Hide loading spinner groupEl.find('.email-signup-form').show(); groupEl.find('.email-submit-loading').hide(); // Display failure msg var target = jQuery(e.target); jQuery(e.target).hide(); jQuery(e.target).parent().find('.alert-danger').show(); } }); } else { groupEl.find('.alert-danger').html('Please enter a valid email address.').show(); } }); forms.off( 'keypress' ).on( 'keypress', function ( e ) { if ( e.which === 13 ) { e.preventDefault(); jQuery( this ).submit(); } }); } }, 100); }); </script>