汉元年八月,刘邦采纳韩信建议,部署还兵关中。他引兵从故道出,连续击破章邯、司马欣、董翳军,夺取了函谷关及其以西地区。
汉二年(公元前205年),刘邦自临晋(今陕西大荔县东)渡黄河,又经洛阳,向东进军。这时,项羽正率军北上山东作战,北至北海,“烧夷城郭、宫室,坑田荣降卒,系虏其老弱妇女,所过多所残灭。齐民相聚叛之”。刘邦利用彭城空虚,率诸侯兵五十六万人大举东伐,又得彭越率兵三万余人来归,遂攻入彭城。项羽闻讯,率三万精兵回师反击。睢水一战,刘邦大败,仅剩数十骑逃到砀(今安徽砀山南)。
刘邦集合逃散的士卒,退至荥阳。诸败军至此会合,又得镇守关中的萧何征集补充兵员送来,汉军复振。刘邦策动九江王英布举兵叛楚,牵制项羽兵力。随后派韩信等攻占魏、赵两地。汉、楚双方在荥阳、成皋一带相持,展开了激烈的争夺。项羽大军曾把刘邦包围在荥阳,刘邦用计得脱,退入关中,留少数兵力固守荥阳。此后,改从武关出军宛、叶(今河南南阳市及叶县南)。项羽引兵南下,汉军坚壁拒战。当时,彭越常在项羽后方断其粮道,又在下邳(今江苏邳县)大破楚军。项羽腹背受敌,只得移兵东击彭越。刘邦乘机北上,再次进军成皋。项羽打败彭越后,回兵攻拔荥阳,再夺成皋。刘邦派卢绾等率师渡白马津(今河南滑县北)南下,与彭越会合,夹击项羽后方,烧毁其粮食积聚。与此同时,韩信也平定了齐地。
汉四年(公元前203年),项羽不得不再次东征彭越,而留大将曹咎守卫成皋。汉军进攻成皋,楚军坚守不出。汉军故意在阵前辱骂,激怒曹咎,待楚军出动半渡氾水时,大破楚军,曹咎自杀。项羽引兵西还,楚汉双方在广武(今河南荥阳东北)相持不下。刘邦封韩信为齐王,征其兵击楚。项羽既多方面受敌,后方供给又被彭越截断,楚军缺粮而士气疲惫,汉军则粮多而士气高涨,汉军居于优势。刘邦趁机跟项羽讲和,双方约定以鸿沟(今河南中牟县)为界,“以西为汉,以东为楚”。
楚汉战争共持续了五年,而两军在荥阳、成皋之间展开激烈争夺即有三年。刘邦的军事力量在相持中逐步由劣势变为优势,项羽则在相持中陷入“兵疲食尽”的困境,被迫同意划鸿沟为界。