Sebastian Vettel was third-fastest for Mercedes’ arch-rivals Ferrari for the race in Shanghai, the 1,000th grand prix in Formula One.
Bottas, who leads the championship by one point from title-holder Hamilton after two races, scorched to a best time of one minute 31.547 seconds.
That was just 0.023 secs ahead of Hamilton.
“The car has been really good this weekend and Lewis also improved a lot in qualifying, it was super close,” said the Finn Bottas.
Fourth on the grid will be the other Ferrari of Charles Leclerc. Fifth was Red Bull’s Max Verstappen and sixth his team-mate Pierre Gasly.
Bottas was the man in form, going fastest in the last two practice sessions.
He had also gone quickest in Q1, but teammate Hamilton was marginally faster in Q2.
A notable casualty in Q2 was former world champion Kimi Raikkonen, the Alfa Romeo veteran who is a crowd favourite in China.
Earlier, Toro Rosso’s Alexander Albon lost control and smashed at high speed towards the end of final practice, so did not take part in qualifying.
The 23-year-old rookie climbed gingerly out of his wrecked car, but only after a huge scare that drew gasps from the crowd in Shanghai.
The Thai-Briton, who is in his first season in F1, careened into a wall as he entered the straight with less than 10 minutes left of third and final practice.
His car was badly mangled and there was a frantic call from engineers asking if he was okay.
He was later given the all-clear but missed qualifying because his ruined car could not be fixed in time.
Albon said that he had been “a bit too greedy”.
“I was obviously pushing, trying to find the limits, but it should have been in qualifying not FP3 (third practice),” he said.
Sunday’s race begins at 2:10 p.m. (0610 GMT).
Download our app and read this and other great stories on the move. Available for Android and iOS.