diff --git a/tokio-codec/src/decoder.rs b/tokio-codec/src/decoder.rs
index f492b0f19..41b950790 100644
--- a/tokio-codec/src/decoder.rs
+++ b/tokio-codec/src/decoder.rs
@@ -16,9 +16,6 @@ use super::Framed;
/// Implementations are able to track state on `self`, which enables
/// implementing stateful streaming parsers. In many cases, though, this type
/// will simply be a unit struct (e.g. `struct HttpDecoder`).
-
-// Note: We can't deprecate this trait, because the deprecation carries through to tokio-codec, and
-// there doesn't seem to be a way to un-deprecate the re-export.
pub trait Decoder {
/// The type of decoded frames.
type Item;
@@ -63,6 +60,46 @@ pub trait Decoder {
/// Finally, if the bytes in the buffer are malformed then an error is
/// returned indicating why. This informs `Framed` that the stream is now
/// corrupt and should be terminated.
+ ///
+ /// # Buffer management
+ ///
+ /// Before returning from the function, implementations should ensure that
+ /// the buffer has appropriate capacity in anticipation of future calls to
+ /// `decode`. Failing to do so leads to inefficiency.
+ ///
+ /// For example, if frames have a fixed length, or if the length of the
+ /// current frame is known from a header, a possible buffer management
+ /// strategy is:
+ ///
+ /// ```no_run
+ /// # use std::io;
+ /// #
+ /// # use bytes::BytesMut;
+ /// # use tokio_codec::Decoder;
+ /// #
+ /// # struct MyCodec;
+ /// #
+ /// impl Decoder for MyCodec {
+ /// // ...
+ /// # type Item = BytesMut;
+ /// # type Error = io::Error;
+ ///
+ /// fn decode(&mut self, src: &mut BytesMut) -> Result