Faits: A. Par contrat de bail du 8 mai 1974, W._ SA (devenue depuis lors X._ SA; ci-après: X._) a donné en location à H.A._ et F.A._ un appartement de six pièces d'une surface de 174 m2 situé au deuxième étage de l'immeuble sis à la rue Charles-Sturm 20, à Genève. Depuis le 1er juillet 1994, le loyer, sans les charges, s'élève à 15'948 fr. par an, soit 1'329 fr. par mois. Par avis officiel du 2 mars 2007, X._ a résilié le bail pour le 30 juin 2007. Le congé a été signifié pour des motifs économiques, afin de relouer l'appartement à un tiers pour un loyer supérieur. B. H.A._ et F.A._ ont saisi la Commission de conciliation en matière de baux et loyers, laquelle a annulé la résiliation du bail. X._ a porté l'affaire devant le Tribunal des baux et loyers du canton de Genève. Dans la procédure, elle a fait état d'objets comparatifs, décrits sur des fiches, dont les loyers étaient censés être déterminants pour établir les loyers usuels dans le quartier. Les locataires ont conclu à l'annulation du congé et, subsidiairement, à la prolongation du bail pour une durée de quatre ans échéant le 30 juin 2011. Par jugement du 17 septembre 2008, le tribunal a annulé le congé; il a jugé qu'aucun des objets présentés par la bailleresse n'était comparable à l'appartement occupé par les locataires et que X._ n'avait ainsi pas démontré qu'elle pourrait relouer l'appartement à un tiers pour un loyer non abusif supérieur au loyer payé par les locataires actuels. Saisie par la bailleresse, la Chambre d'appel en matière de baux et loyers du canton de Genève a confirmé ce jugement par arrêt du 19 juin 2009. X._ a interjeté un recours en réforme. Par arrêt du 15 décembre 2009 (cause 4A_412/2009; ATF 136 III 74), le Tribunal fédéral a admis partiellement le recours, annulé l'arrêt attaqué et renvoyé la cause à l'autorité cantonale pour nouvelle décision. Il a jugé tout d'abord que la cour cantonale avait violé l'art. 269a let. a CO en retenant comme quartier déterminant au sens de cette disposition un périmètre très restreint, qui ne correspondait en particulier ni à un quartier historique, ni à une entité administrative. Afin d'éviter un renvoi inutile, la cour de céans a recherché ensuite si, parmi les neuf objets situés dans ce périmètre trop limité et examinés par la cour cantonale, il y avait tout de même les cinq exemples - exigés par la jurisprudence pour constater les loyers usuels du quartier - comparables à l'appartement occupé par les époux A._; elle est arrivée à la conclusion que tel n'était pas le cas. En conséquence, la cour cantonale était invitée à déterminer si des éléments comparatifs qu'elle avait écartés d'emblée pouvaient être considérés comme compris dans le même quartier que l'appartement de référence et, le cas échéant, à procéder à la comparaison concrète. Par arrêt du 29 mars 2010, la Cour de justice a renvoyé la cause au Tribunal des baux et loyers pour instruction et nouvelle décision au sens des considérants du Tribunal fédéral, avec possibilité pour les parties de compléter leurs allégués. Le 16 décembre 2010, le Tribunal des baux et loyers s'est rendu à la rue Charles-Sturm 20 pour examiner l'immeuble et l'appartement en cause. Selon le procès-verbal établi à cette occasion, l'immeuble a été construit en 1893; en 1979, les façades ont été rénovées et les fenêtres ont été pourvues d'un double vitrage; l'entrée de l'immeuble est munie d'un code d'accès, sans interphone; l'état général du bâtiment, à l'extérieur, est qualifié de moyen; le hall d'entrée de l'immeuble et la cage d'escaliers sont en bon état; la cuisine - ni agencée ni équipée - est ancienne et son état est qualifié de vétuste; le système électrique est ancien; les WC et la salle de bains sont qualifiés d'anciens et de vétustes; les pièces de l'appartement qui n'ont pas été rénovées aux frais des locataires sont décrites comme vétustes. Par jugement du 24 novembre 2011, le Tribunal des baux et loyers a derechef annulé le congé notifié le 2 mars 2007. Dans sa décision, il a tout d'abord délimité le quartier déterminant, dont les contours coïncident en grande partie avec ceux préconisés par la bailleresse; le périmètre fixé comprend tous les immeubles proposés à titre comparatif par la bailleresse, sauf l'exemple n° 46 sis au chemin de l'Escalade, au sud de la surface retenue. Vingt objets comparatifs ont ainsi été examinés. Le tribunal en a écarté neuf qui se trouvaient dans des immeubles édifiés plus de vingt ans avant ou après la construction de l'immeuble de la rue Charles-Sturm 20. Le même sort a été réservé à deux exemples qui présentaient une différence de surface de 25 à 30% avec l'appartement litigieux. Sur les neuf objets comparatifs restants, le tribunal a écarté les exemples nos 10, 12, 1, 27, 31 et 51 en raison de divergences dans les équipements et les accessoires, ainsi que dans l'état de l'immeuble et de l'appartement. Les derniers objets (nos 11, 21 et 33) n'étaient pas en nombre suffisant pour pouvoir procéder à une comparaison valable selon la jurisprudence. Statuant le 10 septembre 2012 sur appel de X._, la Chambre des baux et loyers de la Cour de justice a confirmé le jugement de première instance. C. X._ interjette un recours en matière civile. Elle conclut à l'annulation de l'arrêt cantonal, puis au renvoi de la cause à l'autorité précédente pour instruction complémentaire. A titre alternatif, elle demande au Tribunal fédéral de constater la validité de la résiliation du 2 mars 2007 et de refuser aux époux A._ une prolongation du bail. H.A._ et F.A._ concluent à la confirmation de l'arrêt attaqué et, subsidiairement, au renvoi de la cause à l'autorité cantonale pour qu'elle ordonne à la bailleresse de produire toutes pièces utiles en vue d'effectuer un calcul de rendement. Pour sa part, la cour cantonale se réfère aux considérants de son arrêt.