First off it is advisable to make sure to add an antenna to both the transmitter and receiver. This can be just a simple piece of insulated stranded wire attached to the TX and RX module's ANT terminals. The wire length follows from the frequency. I've used wire about 6.8 inches in length for 433 MHz modules.
To get reliable communications with these low cost RF modules it is necessary to understand that the receivers often detect so much random RF noise from the environment that they are constantly emitting signal transitions at the receiver output pin. Thus the receiver needs to see a good strong signal to lock onto that will override the stray and random noise from the nearby environment. The receiver modules also require some "capture time" to be able to settle into seeing the transmit signal.
I have found these low cost modules to be nearly useless for reliable communications when just trying to be used as a UART extender with NRZ signal modulation. Even worse with a UART type scheme is the variable spacing that can occur between individual bytes that are sent.
When I use these modules I have devised a protocol that sends data bits at a rate of 500 bits per second. The data is sent with a Manchester encoding pattern using a state machine design with a 1 msec interrupt rate on the TX side of the link. A lead-in preamble of about 30 bit times of all 1's is used to lock in the receiver.
For successful Manchester transmission it is necessary to have a SYNC pattern in the data stream that uses a timing pattern that is different than the normal 1T and 2T pulse widths seen in the normal stream. In my protocol I have my sync be a 3T low level followed by a 3T high pulse that comes immediately after the preamble sequence. The data portion of the stream comes immediately after the SYNC in a continuous flow through the end of the data packet.
At my receiver MCU I setup a decoding state machine that is driven off two interrupts, one on the positive edge of the receiver signal and the other on the negative edge of the received signal. In the receiver interrupt routines the time spacing from edge to edge of the detected signal is checked for validity within an expected range. There can be quite a bit of pulse width distortion through the RF link pair so this validation on pulse width needs to be liberal in margin but tight enough to qualify the expected possible Manchester pulse interval timing (1T, 2T and 3T). If any error occurs the receiver aborts the current state and returns to an initial idle state looking again for the SYNC sequence.
Using this scheme I have been able to deploy reasonably reliable RF links that work up to about 100 feet or so. Any system that would deploy a link like this needs to be designed so that the failure of any given data stream does not hang the operations at the receiver end. As such the transmitter should be designed to repeat the transmission on a periodic manner. (Think of this like the low cost garage door openers. They use a similar scheme and transmit as long as the user presses the button and sees that the receiver has detected the signal - i.e. the door is opening or closing). One application where I've deployed these modules is where I have a time clock master transmitter that has accurate battery backed up RTC. It transmits a packet with the current time and date once per minute. The targets are time clock display units that simply run a software clock from the MCU crystal timing. These are accurate for short term but can drift many seconds per day. The target units will see the transmitter packets and when decoded successfully will sync their software clocks to the time seen from the received packet. As such even if the target devices fail to see the time update packets for several minutes or even an hour or so they still continue to operate normally until a validated packet is detected.
Through the use of interrupts on both the transmitter and receiver this system only places an couple of percent processing load on MCUs operating at clock rates of 25 to 50 MHz.