1<?xml version="1.0" encoding="US-ASCII"?>
2<!DOCTYPE rfc SYSTEM "xml2rfc/rfc2629.dtd">
3<?xml-stylesheet type='text/xsl' href='rfc2629.xslt'?>
4<?rfc toc="yes"?>
5<?rfc strict="yes"?>
6<?rfc symrefs="yes"?>
7<?rfc sortrefs="yes" ?>
8<?rfc compact="yes" ?>
9<?rfc subcompact="yes" ?>
10<rfc category="info" docName="draft-stone-memcache-binary-01" ipr="none">
11
12  <front>
13
14    <title> Memcache Binary Protocol </title>
15
16    <author fullname="Aaron Stone" surname="Aaron Stone" role="editor">
17      <organization>Six Apart, Ltd.</organization>
18      <address>
19        <postal>
20          <street>548 4th Street</street>
21          <city>San Francisco</city>
22          <region>CA</region>
23          <code>94107</code>
24          <country>USA</country>
25        </postal>
26        <email>[email protected]</email>
27      </address>
28    </author>
29
30    <date day="14" month="December" year="2007" />
31
32    <area>Applications</area>
33
34    <keyword>memcache memcached cache</keyword>
35
36    <abstract>
37      <t>
38      This memo explains the memcache binary protocol for informational purposes.
39      </t>
40
41      <t>
42      Memcache is a high performance key-value cache. It is intentionally a
43      dumb cache, optimized for speed only. Applications using memcache do
44      not rely on it for data -- a persistent database with guaranteed reliability
45      is strongly recommended -- but applications can run much faster when
46      cached data is available in memcache.
47      </t>
48    </abstract>
49  </front>
50
51  <middle>
52    <section anchor="introduction" title="Introduction">
53      <t>
54      Memcache is a high performance key-value cache. It is intentionally a
55      dumb cache, optimized for speed only. Applications using memcache do
56      not rely on it for data -- a persistent database with guaranteed reliability
57      is strongly recommended -- but applications can run much faster when
58      cached data is available in memcache.
59      </t>
60      <t>
61      Memcache was originally written to make <xref target="LJ">LiveJournal</xref> go faster.
62      It now powers all of the fastest web sites that you love.
63      </t>
64      <section anchor="conventions" title="Conventions Used In This Document">
65        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
66        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
67        document are to be interpreted as described in <xref target="KEYWORDS"/>.
68        </t>
69      </section>
70    </section>
71
72    <section anchor="packet" title="Packet Structure">
73      <t>
74      <figure>
75        <preamble>General format of a packet:</preamble>
76          <artwork>
77    Byte/     0       |       1       |       2       |       3       |
78       /              |               |               |               |
79      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
80      +---------------+---------------+---------------+---------------+
81     0/ HEADER                                                        /
82      /                                                               /
83      /                                                               /
84      /                                                               /
85      +---------------+---------------+---------------+---------------+
86    16/ COMMAND-SPECIFIC EXTRAS (as needed)                           /
87     +/  (note length in th extras length header field)               /
88      +---------------+---------------+---------------+---------------+
89     m/ Key (as needed)                                               /
90     +/  (note length in key length header field)                     /
91      +---------------+---------------+---------------+---------------+
92     n/ Value (as needed)                                             /
93     +/  (note length is total body length header field, minus        /
94     +/   sum of the extras and key length body fields)               /
95      +---------------+---------------+---------------+---------------+
96     Total 16 bytes
97      </artwork></figure>
98      </t>
99
100      <t>
101      <figure>
102        <preamble>Request header:</preamble>
103          <artwork>
104    Byte/     0       |       1       |       2       |       3       |
105       /              |               |               |               |
106      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
107      +---------------+---------------+---------------+---------------+
108     0| Magic         | Opcode        | Key length                    |
109      +---------------+---------------+---------------+---------------+
110     4| Extras length | Data type     | Reserved                      |
111      +---------------+---------------+---------------+---------------+
112     8| Total body length                                             |
113      +---------------+---------------+---------------+---------------+
114    12| Message ID                                                    |
115      +---------------+---------------+---------------+---------------+
116    Total 16 bytes
117      </artwork></figure>
118      </t>
119
120      <t>
121      <figure>
122        <preamble>Response header:</preamble>
123          <artwork>
124    Byte/     0       |       1       |       2       |       3       |
125       /              |               |               |               |
126      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
127      +---------------+---------------+---------------+---------------+
128     0| Magic         | Opcode        | Status                        |
129      +---------------+---------------+---------------+---------------+
130     4| Extras length | Data type     | Reserved                      |
131      +---------------+---------------+---------------+---------------+
132     8| Total body length                                             |
133      +---------------+---------------+---------------+---------------+
134    12| Message ID                                                    |
135      +---------------+---------------+---------------+---------------+
136    Total 16 bytes
137      </artwork></figure>
138      </t>
139
140      <t>
141        Header fields:
142        <list hangIndent="20" style="hanging">
143          <t hangText="Magic">Magic number.</t>
144          <t hangText="Opcode">Command code.</t>
145          <t hangText="Key length">Length in bytes of the text key that follows the command extras.</t>
146          <t hangText="Status">Status of the response (non-zero on error).</t>
147          <t hangText="Extras length">Length in bytes of the command extras.</t>
148          <t hangText="Data type">Reserved for future use (Sean is using this soon).</t>
149          <t hangText="Reserved">Really reserved for future use (up for grabs).</t>
150          <t hangText="Total body length">Length in bytes of extra + key + value.</t>
151          <t hangText="Message ID">Will be copied back to you in the response.
152              FIXME: Can this be used to organize <xref target="UDP"/> packets?</t>
153        </list>
154      </t>
155    </section>
156
157    <section anchor="values" title="Defined Values">
158      <section anchor="value-magic" title="Magic Byte">
159        <t>
160        <list hangIndent="8" style="hanging">
161          <t hangText="0x80">Request packet for this protocol version</t>
162          <t hangText="0x81">Response packet for this protocol version</t>
163        </list>
164        </t>
165
166        <t>
167          Magic byte / version. For each version of the protocol, we'll use a
168          different request/reponse value pair. This is useful for protocol
169          analyzers to know what a packet is in isolation from which direction
170          it is moving. Note that it is common to run a memcached instance on a
171          host that also runs an application server. Such a host will both send
172          and receive memcache packets.
173        </t>
174
175        <t>
176          The version should hopefully correspond only to different meanings of
177          the command byte. In an ideal world, we will not change the header
178          format. As reserved bytes are given defined meaning, the protocol
179          version / magic byte values should be incremented.
180        </t>
181
182        <t>
183          Traffic analysis tools are encouraged to identify memcache packets
184          and provide detailed interpretation if the magic bytes are recognized
185          and otherwise to provide a generic breakdown of the packet. Note that
186          the key and value positions can always be identified even if the magic
187          byte or command opcode are not recognized.
188        </t>
189      </section>
190
191      <section anchor="value-status" title="Response Status">
192        <t>
193        Possible values of this two-byte field:
194        <list hangIndent="8" style="hanging">
195          <t hangText="0x0000">No error</t>
196          <t hangText="0x0081">Unknown command</t>
197          <t hangText="0x0001">Key not found</t>
198          <t hangText="0x0002">Key exists</t>
199        </list>
200        </t>
201      </section>
202
203      <section anchor="value-opcodes" title="Command Opcodes">
204        <t>
205        Possible values of the one-byte field:
206        <list hangIndent="8" style="hanging">
207          <t hangText="0x00">Get</t>
208          <t hangText="0x01">Set</t>
209          <t hangText="0x02">Add</t>
210          <t hangText="0x03">Replace</t>
211          <t hangText="0x04">Delete</t>
212          <t hangText="0x05">Increment</t>
213          <t hangText="0x06">Decrement</t>
214          <t hangText="0x07">Quit</t>
215          <t hangText="0x08">Flush</t>
216          <t hangText="0x09">GetQ</t>
217          <t hangText="0x0A">No-op</t>
218          <t hangText="0x0B">Version</t>
219        </list>
220        </t>
221      </section>
222
223      <section anchor="value-types" title="Data Types">
224        <t>
225        Possible values of the one-byte field:
226        <list hangIndent="8" style="hanging">
227          <t hangText="0x00">Raw bytes</t>
228        </list>
229        </t>
230      </section>
231    </section>
232
233    <section title="Commands">
234      <section anchor="command-get" title="Get, Get Quietly">
235        <t>
236        <list style="empty">
237          <t>MUST have extras.</t>
238          <t>MUST have key.</t>
239          <t>MUST NOT have value.</t>
240        </list>
241        </t>
242
243        <t>
244        <list style="symbols">
245          <t>4 byte flags</t>
246          <t>8 byte data version check</t>
247        </list>
248        </t>
249
250        <t>
251      <figure>
252        <preamble>Extra data for get/getq:</preamble>
253          <artwork>
254    Byte/     0       |       1       |       2       |       3       |
255       /              |               |               |               |
256      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
257      +---------------+---------------+---------------+---------------+
258     0| Data version check                                            |
259      |                                                               |
260      +---------------+---------------+---------------+---------------+
261     8| Flags                                                         |
262      +---------------+---------------+---------------+---------------+
263    Total 12 bytes
264      </artwork></figure>
265        </t>
266
267        <t>
268          The get command gets a single key. The getq command is both mum
269          on cache miss and quiet, holding its response until a non-quiet
270          command is issued.
271        </t>
272
273        <t>
274          You're not guaranteed a response to a getq cache hit until
275          you send a non-getq command later, which uncorks the
276          server which bundles up IOs to send to the client in one go.
277        </t>
278
279        <t>
280          Clients should implement multi-get (still important for
281          reducing network roundtrips!) as n pipelined requests, the
282          first n-1 being getq, the last being a regular
283          get.  that way you're guaranteed to get a response, and
284          you know when the server's done.  you can also do the naive
285          thing and send n pipelined gets, but then you could potentially
286          get back a lot of "NOT_FOUND!" error code packets.
287          alternatively, you can send 'n' getqs, followed by an 'echo'
288          or 'noop' command.
289        </t>
290
291      </section>
292
293      <section anchor="command-delete" title="Delete">
294        <t>
295        <list style="empty">
296          <t>MAY have extras (FIXME: Is it OK to issue a delete without extras?).</t>
297          <t>MUST have key.</t>
298          <t>MUST NOT have value.</t>
299        </list>
300        </t>
301
302        <t>
303          <list style="symbols">
304            <t>4 byte expiration time</t>
305          </list>
306        </t>
307
308        <t>
309      <figure>
310        <preamble>Extra data for delete:</preamble>
311          <artwork>
312    Byte/     0       |       1       |       2       |       3       |
313       /              |               |               |               |
314      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
315      +---------------+---------------+---------------+---------------+
316     0| Expiration                                                    |
317      +---------------+---------------+---------------+---------------+
318    Total 4 bytes
319      </artwork></figure>
320        </t>
321
322        <t>
323          When allows you to 'reserve' a key. When 'when' is set
324          for, say, ten seconds in the future, the 'add' and 'replace' operations will fail for that key
325          until ten seconds from now.  The 'set' operation will succeed regardless of any reserved deletes.
326          FIXME: Is the reservation also cancelled? Say there's a delete with a 10 second hold. Two seconds
327          later, an 'add' is received. It fails. Two second later, a 'set' is received. Is succeeds unconditionally.
328          What if another 'add' is received two more seconds later (a total of six seconds since the original
329          10 second delete-hold, thus still within its purview).
330        </t>
331
332      </section>
333
334      <section anchor="command-set" title="Set, Add, Replace">
335        <t>
336        <list style="empty">
337          <t>MUST have extras.</t>
338          <t>MUST have key.</t>
339          <t>MUST have value.</t>
340        </list>
341        </t>
342
343        <t>
344          <list style="symbols">
345            <t>4 byte flags</t>
346            <t>4 byte expiration time</t>
347            <t>8 byte data version check</t>
348          </list>
349        </t>
350
351        <t>
352        <figure>
353          <preamble>Extra data for set/add/replace:</preamble>
354            <artwork>
355    Byte/     0       |       1       |       2       |       3       |
356       /              |               |               |               |
357      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
358      +---------------+---------------+---------------+---------------+
359     0| Data version check                                            |
360      |                                                               |
361      +---------------+---------------+---------------+---------------+
362     8| Flags                                                         |
363      +---------------+---------------+---------------+---------------+
364    12| Expiration                                                    |
365      +---------------+---------------+---------------+---------------+
366    Total 16 bytes
367        </artwork></figure>
368        </t>
369
370        <t>
371        If the Data Version Check is present and nonzero, the set MUST succeed if the
372        key exists and has a version identifier identical to the provided value, and
373	MUST NOT succeed if the key does not exist or has a different version identifier.
374	The set response packet will include the same values in all three fields.
375        </t>
376
377        <t>
378        If the Data Version Check is zero, the set MUST succeed unconditionally.
379	The set response packet will include idential values for flags and expiration,
380	and a new value for Data Version Check, which the client SHOULD keep track of.
381        </t>
382
383	<t>
384	The key MAY be reserved according to <xref target="command-delete"/>,
385	causing the set to fail.
386	</t>
387      </section>
388
389      <section title="noop">
390        <t>
391        <list style="empty">
392          <t>MUST NOT have extras.</t>
393          <t>MUST NOT have key.</t>
394          <t>MUST NOT have value.</t>
395        </list>
396        </t>
397
398        <t>
399        Used as a keep alive. Flushes outstanding getq's.
400        </t>
401      </section>
402
403      <section anchor="command-incr" title="Increment, Decrement">
404        <t>
405        <list style="empty">
406          <t>MUST have extras.</t>
407          <t>MUST have key.</t>
408          <t>MUST NOT have value.</t>
409        </list>
410        </t>
411
412        <t>
413          <list style="symbols">
414            <t>8 byte value to add / subtract (FIXME: Is this unsigned?)</t>
415            <t>8 byte initial value (unsigned)</t>
416            <t>4 byte expiration time</t>
417          </list>
418        </t>
419
420        <t>
421      <figure>
422        <preamble>Extra data for incr/decr:</preamble>
423          <artwork>
424    Byte/     0       |       1       |       2       |       3       |
425       /              |               |               |               |
426      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
427      +---------------+---------------+---------------+---------------+
428     0| Amount to add                                                 |
429      |                                                               |
430      +---------------+---------------+---------------+---------------+
431     8| Initial value                                                 |
432      |                                                               |
433      +---------------+---------------+---------------+---------------+
434    16| Expiration                                                    |
435      +---------------+---------------+---------------+---------------+
436    Total 20 bytes
437      </artwork></figure>
438        </t>
439
440        <t>
441      <figure>
442        <preamble>incr/decr response body:</preamble>
443          <artwork>
444    Byte/     0       |       1       |       2       |       3       |
445       /              |               |               |               |
446      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
447      +---------------+---------------+---------------+---------------+
448     0| 64-bit unsigned response.                                     |
449      |                                                               |
450      +---------------+---------------+---------------+---------------+
451    Total 8 bytes
452      </artwork></figure>
453        </t>
454
455        <t>
456          These commands will either add or remove the specified
457          amount to the requested counter.
458
459          If the counter does not exist, one of two things may happen:
460
461          <list style="numbers">
462          <t>If the expiration value is all one-bits (0xffffffff), the
463             operation will fail with NOT_FOUND.</t>
464          <t>For all other expiration values, the operation will succeed
465             by seeding the value for this key with the provided initial
466             value to expire with the provided expiration time.</t>
467          </list>
468        </t>
469
470        <t>
471          Note that in the creation case, flags will be set to zero
472          (FIXME:  Should they be provided here as well?)
473        </t>
474      </section>
475    </section>
476
477    <section title="Example Session">
478      <t>
479      We start up our application, and it asks for the value associated with the 'Hello' key.
480      <figure>
481        <preamble>Get request:</preamble>
482          <artwork>
483    Byte/     0       |       1       |       2       |       3       |
484       /              |               |               |               |
485      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
486      +---------------+---------------+---------------+---------------+
487     0| 0x80          | 0x00          | 5 in big endian (BE)          |
488      +---------------+---------------+---------------+---------------+
489      | 12 in BE      | 0x00          |                               |
490      +---------------+---------------+---------------+---------------+
491      | 17 in BE                                                      |
492      +---------------+---------------+---------------+---------------+
493      | 0xDEADBEEF                                                    |
494      +---------------+---------------+---------------+---------------+
495    16| 0x00000000                                                    |
496      +---------------+---------------+---------------+---------------+
497    24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
498      |                                                               |
499      +---------------+---------------+---------------+---------------+
500    28| 'H'             'e'             'l'             'l'           |
501      | 'o'           |
502      +---------------+
503    Total 33 bytes (16 header + 12 get-extras + 5 key)
504      </artwork></figure>
505      </t>
506
507      <t>
508      Since nobody has set this key, it returns not found.
509      <figure>
510        <preamble>Get response:</preamble>
511          <artwork>
512    Byte/     0       |       1       |       2       |       3       |
513       /              |               |               |               |
514      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
515      +---------------+---------------+---------------+---------------+
516     0| 0x81          | 0x00          | 0x0001                        |
517      +---------------+---------------+---------------+---------------+
518      | 0 in BE       | 0x00          |                               |
519      +---------------+---------------+---------------+---------------+
520      | 0 in BE                                                       |
521      +---------------+---------------+---------------+---------------+
522      | 0xDEADBEEF                                                    |
523      +---------------+---------------+---------------+---------------+
524    Total 16 bytes
525      </artwork></figure>
526      </t>
527
528      <t>
529      Well, looks like we need to set the key! Let's set it to expire on
530      December 15, 2007 at 9:51:09 PM.
531      <figure>
532        <preamble>Set request:</preamble>
533          <artwork>
534    Byte/     0       |       1       |       2       |       3       |
535       /              |               |               |               |
536      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
537      +---------------+---------------+---------------+---------------+
538     0| 0x80          | 0x01          | 5 in BE                       |
539      +---------------+---------------+---------------+---------------+
540      | 16 in BE      | 0x00          |                               |
541      +---------------+---------------+---------------+---------------+
542      | 26 in BE                                                      |
543      +---------------+---------------+---------------+---------------+
544      | 0xDA7ABA5E                                                    |
545      +---------------+---------------+---------------+---------------+
546    16| 0x00000000                                                    |
547      +---------------+---------------+---------------+---------------+
548    20| 0xDCCB4674                                                    |
549      +---------------+---------------+---------------+---------------+
550    24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
551      |                                                               |
552      +---------------+---------------+---------------+---------------+
553    32| 'H'             'e'             'l'             'l'           |
554      | 'o'           | 'W'             'o'             'r'           |
555      | 'l'             'd'           |
556      +---------------+---------------+
557    Total 42 bytes (16 header + 16 set-extras + 5 key + 5 value)
558      </artwork></figure>
559      </t>
560
561      <t>
562      The set succeeds.
563      <figure>
564        <preamble>Set response:</preamble>
565          <artwork>
566    Byte/     0       |       1       |       2       |       3       |
567       /              |               |               |               |
568      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
569      +---------------+---------------+---------------+---------------+
570     0| 0x81          | 0x01          | 0x0000                        |
571      +---------------+---------------+---------------+---------------+
572      | 16 in BE      | 0x00          |                               |
573      +---------------+---------------+---------------+---------------+
574      | 16 in BE                                                      |
575      +---------------+---------------+---------------+---------------+
576      | 0xDA7ABA5E                                                    |
577      +---------------+---------------+---------------+---------------+
578    16| 0x00000000                                                    |
579      +---------------+---------------+---------------+---------------+
580    20| 0xDCCB4674                                                    |
581      +---------------+---------------+---------------+---------------+
582    24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
583      |                                                               |
584      +---------------+---------------+---------------+---------------+
585    Total 32 bytes (16 header + 16 set-extras)
586      </artwork></figure>
587      </t>
588
589      <t>
590      If the original get request is sent again, the key would be found.
591      <figure>
592        <preamble>Get response:</preamble>
593          <artwork>
594    Byte/     0       |       1       |       2       |       3       |
595       /              |               |               |               |
596      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
597      +---------------+---------------+---------------+---------------+
598     0| 0x81          | 0x00          | 0x00          |               |
599      +---------------+---------------+---------------+---------------+
600      | 12 in BE      | 0x00          |                               |
601      +---------------+---------------+---------------+---------------+
602      | 17 in BE                                                      |
603      +---------------+---------------+---------------+---------------+
604      | 0xDEADBEEF                                                    |
605      +---------------+---------------+---------------+---------------+
606    16| 0xDCCB4674                                                    |
607      +---------------+---------------+---------------+---------------+
608    24| 0xDECAF 0x15 0xBAD 0xC0FFEE                                   |
609      |                                                               |
610      +---------------+---------------+---------------+---------------+
611    28| 'W'             'o'             'r'             'l'           |
612      | 'd'           |
613      +---------------+
614    Total 33 bytes (16 header + 12 get-extras + 5 value)
615      </artwork></figure>
616      </t>
617    </section>
618
619    <section anchor="security" title="Security Considerations">
620      <t>
621      Memcache has no authentication or security layers whatsoever.  It is
622      RECOMMENDED that memcache be deployed strictly on closed, protected,
623      back-end networks within a single data center, within a single cluster of
624      servers, or even on a single host, providing shared caching for multiple
625      applications. Memcache MUST NOT be made available on a public network.
626      </t>
627    </section>
628
629  </middle>
630
631  <back>
632    <references title="Normative References">
633      <reference anchor="LJ">
634        <front>
635          <title>LJ NEEDS MOAR SPEED</title>
636          <author fullname="Brad Fitzpatrick">
637            <organization>Danga Interactive</organization>
638          </author>
639          <date day="5" month="10" year="1999" />
640          <abstract>
641            <t>http://www.livejournal.com/</t>
642          </abstract>
643        </front>
644      </reference>
645      <dwdrfc-ref anchor='UDP' src='http://xml.resource.org/public/rfc/bibxml/reference.RFC.0768.xml'/>
646      <dwdrfc-ref anchor='KEYWORDS' src='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml'/>
647    </references>
648
649    <section anchor="acknowledgments" title="Acknowledgments">
650      <t>
651      Thanks to Brad Fitzpatrick, Anatoly Vorobey, Steven Grimm, and Dustin
652      Sallings, for their work on the memcached server.
653      </t>
654
655      <t>
656      Thanks to Sean Chittenden, Jonathan Steinert, Brian Aker, Evan Martin,
657      Nathan Neulinger, Eric Hodel, Michael Johnson, Paul Querna, Jamie
658      McCarthy, Philip Neustrom, Andrew O'Brien, Josh Rotenberg, Robin H.
659      Johnson, Tim Yardley, Paolo Borelli, Eli Bingham, Jean-Francois
660      Bustarret, Paul G, Paul Lindner, Alan Kasindorf, Chris Goffinet, Tomash
661      Brechko, and others for their work reporting bugs and maintaining
662      memcached client libraries and bindings in many languages.
663      </t>
664    </section>
665  </back>
666
667</rfc>
668
669