At a Sunset Boulevard mansion, the body of Joe Gillis floats in the swimming pool. In a flashback, Joe relates the events leading to his death.
Six months earlier, down-on-his-luck screenwriter Joe tries selling Paramount Pictures producer Sheldrake on a story he submitted. Script reader Betty Schaefer harshly critiques it in Joe's presence, unaware that he is the author. Later, while fleeing from repossession men seeking his car, Joe turns into the driveway of a seemingly deserted mansion. After concealing the car, he hears a woman calling him, apparently mistaking him for someone else. Ushered in by Max, her butler, Joe recognizes the woman as long-forgotten silent film star Norma Desmond. Learning he is a writer, she asks his opinion of a script she has written for a film about Salome. She plans to play the role herself in a comeback. Joe finds her script abysmal, but flatters her into hiring him as a script doctor.
Moved into Norma's mansion at her insistence, Joe resents but gradually accepts his dependent situation. He sees that Norma refuses to face the fact that her fame has evaporated and learns the fan letters she still receives are secretly written by Max, who tells him Norma is subject to depression and has made suicide attempts.
Norma lavishes attention on Joe and buys him expensive clothes. At her New Year's Eve party, he discovers he is the only guest and realizes she has fallen in love with him. He tries to let her down gently, but she slaps him and retreats to her room. Joe visits his friend Artie Green to ask about staying at his place. At Artie's party, he again meets Betty, who he learns is Artie's girl. Betty thinks a scene in one of Joe's scripts has potential, but Joe is uninterested. When Joe phones Max to have him pack his things, Max tells him Norma cut her wrists with his razor. Joe returns to Norma.
Norma has Max deliver the edited Salome script to her former director, Cecil B. DeMille, at Paramount. She starts getting calls from Paramount executive Gordon Cole, but petulantly refuses to speak to anyone except DeMille. Eventually, she has Max drive her and Joe to Paramount in her 1929 Isotta Fraschini. The older studio employees warmly greet her. DeMille receives her affectionately and treats her with great respect, tactfully evading her questions about Salome. Meanwhile, Max learns that Cole merely wants to rent her unusual car for a film.
Preparing for her imagined comeback, Norma undergoes rigorous beauty treatments. Joe secretly works nights at Betty's Paramount office, collaborating on an original screenplay. His moonlighting is found out by Max, who reveals that he was once a respected film director. He discovered Norma as a teenage girl, made her a star and was her first husband. After she divorced him, he found life without her unbearable and abandoned his career to become her servant.
Although Betty is engaged to Artie, she and Joe fall in love. Norma discovers a manuscript with Joe's and Betty's names on it. She phones Betty and insinuates what sort of man Joe really is. Joe, overhearing, invites Betty to come see for herself. When she arrives, he pretends he is satisfied being a kept man, but after she tearfully leaves, he packs to return to his old Ohio newspaper job. He disregards Norma's threat to kill herself and the gun she shows him to back it up. He bluntly tells her the public has forgotten her, there will be no comeback, and the fan letters are from Max. As Joe walks away, Norma shoots him three times. He falls into the pool.
The flashback ends. The house is filled with police and reporters. Norma, having lost touch with reality, believes the newsreel cameras are there to film Salome. Max and the police play along. Max sets up a scene for her and calls "Action!" As the cameras roll, Norma dramatically descends her grand staircase. She pauses and makes an impromptu speech about how happy she is to be making a film again, ending with: "All right, Mr. DeMille, I'm ready for my close-up."

Question: Who is secretly writing fan mail to Norma?
Answer: Max.
Alternative answer: Max