diff --git a/server.py b/server.py
index 5f92e8ec1edca281b5c9f9a325cb14251dafe12d..3af97b5a8ef771c40c71ec0a516d9fdf404d3783 100755
--- a/server.py
+++ b/server.py
@@ -351,9 +351,9 @@ def list_protocols():
         protocoltype_id = int(request.args.get("protocoltype_id"))
     except (ValueError, TypeError):
         pass
-    open = -1
+    state_open = -1
     try:
-        open = int(request.args.get("open"))
+        state_open = int(request.args.get("state_open"))
     except (ValueError, TypeError):
         pass
     search_term = request.args.get("search")
@@ -362,8 +362,8 @@ def list_protocols():
     if protocoltype_id is not None:
         search_form.protocoltype_id.data = protocoltype_id
         protocoltype = ProtocolType.query.filter_by(id=protocoltype_id).first()
-    if open is not None:
-        search_form.open.data = open
+    if state_open is not None:
+        search_form.state_open.data = state_open
     if search_term is not None:
         search_form.search.data = search_term
     protocol_query = Protocol.query
@@ -398,8 +398,8 @@ def list_protocols():
             protocol for protocol in protocols
             if protocol.protocoltype.id == protocoltype_id
         ]
-    if open is not None and open != -1:
-        protocol_done = bool(open)
+    if state_open is not None and state_open != -1:
+        protocol_done = bool(state_open)
         protocols = [
             protocol for protocol in protocols
             if protocol.is_done() == protocol_done
@@ -440,14 +440,16 @@ def list_protocols():
             search_results[protocol] = " …<br />\n".join(formatted_lines)
     protocols = sorted(protocols, key=lambda protocol: protocol.date, reverse=True)
     page = _get_page()
-    page_count = int(math.ceil(len(protocols) / config.PAGE_LENGTH))
+    page_length = _get_page_length()
+    page_count = int(math.ceil(len(protocols) / page_length))
     if page >= page_count:
         page = 0
-    begin_index = page * config.PAGE_LENGTH
-    end_index = (page + 1) * config.PAGE_LENGTH
+    begin_index = page * page_length
+    end_index = (page + 1) * page_length
+    max_page_length_exp = math.ceil(math.log10(len(protocols)))
     protocols = protocols[begin_index:end_index]
     protocols_table = ProtocolsTable(protocols, search_results=search_results)
-    return render_template("protocols-list.html", protocols=protocols, protocols_table=protocols_table, search_form=search_form, page=page, page_count=page_count, page_diff=config.PAGE_DIFF, protocoltype_id=protocoltype_id, search_term=search_term, open=open)
+    return render_template("protocols-list.html", protocols=protocols, protocols_table=protocols_table, search_form=search_form, page=page, page_count=page_count, page_diff=config.PAGE_DIFF, protocoltype_id=protocoltype_id, search_term=search_term, state_open=state_open, page_length=page_length, max_page_length_exp=max_page_length_exp)
 
 @app.route("/protocol/new", methods=["GET", "POST"])
 @login_required
@@ -781,6 +783,15 @@ def _get_page():
     except ValueError:
         return 0
 
+def _get_page_length():
+    try:
+        page_length = request.args.get("page_length")
+        if page_length is None:
+            return config.PAGE_LENGTH
+        return int(page_length)
+    except ValueError:
+        return config.PAGE_LENGTH
+
 @app.route("/todos/list")
 @login_required
 def list_todos():
@@ -791,9 +802,9 @@ def list_todos():
         protocoltype_id = int(request.args.get("protocoltype_id"))
     except (ValueError, TypeError):
         pass
-    open = -1
+    state_open = -1
     try:
-        open = int(request.args.get("open"))
+        state_open = int(request.args.get("state_open"))
     except (ValueError, TypeError):
         pass
     search_term = request.args.get("search")
@@ -802,8 +813,8 @@ def list_todos():
     if protocoltype_id is not None:
         search_form.protocoltype_id.data = protocoltype_id
         protocoltype = ProtocolType.query.filter_by(id=protocoltype_id).first()
-    if open is not None:
-        search_form.open.data = open
+    if state_open is not None:
+        search_form.state_open.data = state_open
     if search_term is not None:
         search_form.search.data = search_term
     todos = [
@@ -815,8 +826,8 @@ def list_todos():
             todo for todo in todos
             if todo.protocoltype.id == protocoltype_id
         ]
-    if open is not None and open != -1:
-        todo_done = bool(open)
+    if state_open is not None and state_open != -1:
+        todo_done = bool(state_open)
         todos = [
             todo for todo in todos
             if todo.is_done() == todo_done
@@ -831,14 +842,16 @@ def list_todos():
         return (not todo.is_done(), todo.get_id())
     todos = sorted(todos, key=_sort_key, reverse=True)
     page = _get_page()
-    page_count = int(math.ceil(len(todos) / config.PAGE_LENGTH))
+    page_length = _get_page_length()
+    page_count = int(math.ceil(len(todos) / page_length))
     if page >= page_count:
         page = 0
-    begin_index = page * config.PAGE_LENGTH
-    end_index = (page + 1) * config.PAGE_LENGTH
+    begin_index = page * page_length
+    end_index = (page + 1) * page_length
+    max_page_length_exp = math.ceil(math.log10(len(todos)))
     todos = todos[begin_index:end_index]
     todos_table = TodosTable(todos)
-    return render_template("todos-list.html", todos=todos, todos_table=todos_table, search_form=search_form, page=page, page_count=page_count, page_diff=config.PAGE_DIFF, protocoltype_id=protocoltype_id, search_term=search_term, open=open)
+    return render_template("todos-list.html", todos=todos, todos_table=todos_table, search_form=search_form, page=page, page_count=page_count, page_diff=config.PAGE_DIFF, protocoltype_id=protocoltype_id, search_term=search_term, state_open=state_open, page_length=page_length, max_page_length_exp=max_page_length_exp)
 
 @app.route("/todo/new", methods=["GET", "POST"])
 @login_required
@@ -988,14 +1001,17 @@ def list_decisions():
     decisions = sorted(decisions, key=lambda d: d.protocol.date, reverse=True)
         
     page = _get_page()
-    page_count = int(math.ceil(len(decisions) / config.PAGE_LENGTH))
+    page_length = _get_page_length()
+
+    page_count = int(math.ceil(len(decisions) / page_length))
     if page >= page_count:
         page = 0
-    begin_index = page * config.PAGE_LENGTH
-    end_index = (page + 1) * config.PAGE_LENGTH
+    begin_index = page * page_length
+    end_index = (page + 1) * page_length
+    max_page_length_exp = math.ceil(math.log10(len(decisions)))
     decisions = decisions[begin_index:end_index]
     decisions_table = DecisionsTable(decisions)
-    return render_template("decisions-list.html", decisions=decisions, decisions_table=decisions_table, search_form=search_form, page=page, page_count=page_count, page_diff=config.PAGE_DIFF, protocoltype_id=protocoltype_id, search_term=search_term, decisioncategory_id=decisioncategory_id)
+    return render_template("decisions-list.html", decisions=decisions, decisions_table=decisions_table, search_form=search_form, page=page, page_count=page_count, page_diff=config.PAGE_DIFF, protocoltype_id=protocoltype_id, search_term=search_term, decisioncategory_id=decisioncategory_id, page_length=page_length, max_page_length_exp=max_page_length_exp)
 
 @app.route("/document/download/<int:document_id>")
 @db_lookup(Document)
diff --git a/static/css/style.css b/static/css/style.css
index fa1d2352bb21691e9b3efa53a6d90a181671807e..c57ecdf1cf96e2110386255551eed4f00137b901 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -37,7 +37,7 @@ input[type="file"] {
     text-align: center;
 }
 
-.centered > a {
+.centered > a, .centered > span {
     margin: 8px;
 }
 
diff --git a/templates/decisions-list.html b/templates/decisions-list.html
index 42e6712745f9fa7551cf0996b207344923ca39e5..a6c3928e90ecad199da15e62777641b49f95f777 100644
--- a/templates/decisions-list.html
+++ b/templates/decisions-list.html
@@ -2,28 +2,14 @@
 {% from "macros.html" import render_table, render_form %}
 {% block title %}Beschlüsse{% endblock %}
 
-{% macro page_link(page, text) %}
-    <a href="{{url_for(request.endpoint, page=page, protocoltype=protocoltype_id, search=search_term, decisioncategory_id=decisioncategory_id)}}">{{text}}</a>
+{% macro page_link(text, _page=None, _page_length=None) %}
+    <a href="{{url_for(request.endpoint, page=_page or page, protocoltype=protocoltype_id, search=search_term, decisioncategory_id=decisioncategory_id, page_length=_page_length or page_length)}}">{{text}}</a>
 {% endmacro %}
 
 {% block content %}
 <div class="container">
     {{render_form(search_form, class_="form-inline", action_url=url_for("list_decisions"), action_text="Suchen", labels_visible=False, method="GET")}}
     {{render_table(decisions_table)}}
-    <div class="centered">
-        {% if page > page_diff %}
-            {{page_link(0, "<<")}}
-        {% endif %}
-        {% for p in range(max(0, page - page_diff), min(page_count, page + page_diff + 1)) %}
-            {% if p != page %}
-                {{page_link(p, p + 1)}}
-            {% else %}
-                Seite {{p + 1}}
-            {% endif %}
-        {% endfor %}
-        {% if page < page_count - page_diff - 1 %}
-            {{page_link(page_count - 1, ">>")}}
-        {% endif %}
-    </div>
+    {% include "pagination-footer.html" %}
 </div>
 {% endblock %}
diff --git a/templates/pagination-footer.html b/templates/pagination-footer.html
new file mode 100644
index 0000000000000000000000000000000000000000..1f34556743d148f291e56d4c2fcbb1a313dce21b
--- /dev/null
+++ b/templates/pagination-footer.html
@@ -0,0 +1,27 @@
+<div class="centered">
+    {% if page > page_diff %}
+        {{page_link("<<", _page=0)}}
+    {% endif %}
+    {% for p in range(max(0, page - page_diff), min(page_count, page + page_diff + 1)) %}
+        {% if p != page %}
+            {{page_link(p + 1, _page=p)}}
+        {% else %}
+            Seite {{p + 1}}
+        {% endif %}
+    {% endfor %}
+    {% if page < page_count - page_diff - 1 %}
+        {{page_link(">>", _page=page_count - 1)}}
+    {% endif %}
+</div>
+<div class="centered">
+    pro Seite:
+    {% for exponent in range(1, max_page_length_exp+1) %}
+        {% set _page_length=10**exponent %}
+        {% if _page_length != page_length %}
+            {{page_link(_page_length, _page_length=_page_length)}}
+        {% else %}
+            <span>{{_page_length}}</span>
+        {% endif %}
+    {% endfor %}
+</div>
+
diff --git a/templates/protocols-list.html b/templates/protocols-list.html
index 99f7d378d00e99da8ecc02c95ee4d86b01e4161c..c3a2d36abf32d7096997a7ee07aa88520d958702 100644
--- a/templates/protocols-list.html
+++ b/templates/protocols-list.html
@@ -2,28 +2,14 @@
 {% from "macros.html" import render_table, render_form %}
 {% block title %}Protokolle{% endblock %}
 
-{% macro page_link(page, text) %}
-    <a href="{{url_for(request.endpoint, page=page, protocoltype=protocoltype_id, search=search_term, open=open)}}">{{text}}</a>
+{% macro page_link(text, _page=None, _page_length=None) %}
+    <a href="{{url_for(request.endpoint, page=_page or page, protocoltype=protocoltype_id, search=search_term, state_open=state_open, page_length=_page_length or page_length)}}">{{text}}</a>
 {% endmacro %}
 
 {% block content %}
 <div class="container">
     {{render_form(search_form, class_="form-inline", action_url=url_for("list_protocols"), action_text="Suchen", labels_visible=False, method="GET")}}
     {{render_table(protocols_table)}}
-    <div class="centered">
-        {% if page > page_diff %}
-            {{page_link(0, "<<")}}
-        {% endif %}
-        {% for p in range(max(0, page - page_diff), min(page_count, page + page_diff + 1)) %}
-            {% if p != page %}
-                {{page_link(p, p + 1)}}
-            {% else %}
-                Seite {{p + 1}}
-            {% endif %}
-        {% endfor %}
-        {% if page < page_count - page_diff - 1 %}
-            {{page_link(page_count - 1, ">>")}}
-        {% endif %}
-    </div>
+    {% include "pagination-footer.html" %}
 </div>
 {% endblock %}
diff --git a/templates/todos-list.html b/templates/todos-list.html
index a1816bbe690cd7f170c09334c938495f887a3add..49f8134288b60a8ad9b2b914cce1d135baeacd7e 100644
--- a/templates/todos-list.html
+++ b/templates/todos-list.html
@@ -2,28 +2,14 @@
 {% from "macros.html" import render_table, render_form %}
 {% block title %}Todos{% endblock %}
 
-{% macro page_link(page, text) %}
-    <a href="{{url_for(request.endpoint, page=page, protocoltype=protocoltype_id, search=search_term, open=open)}}">{{text}}</a>
+{% macro page_link(text, _page=None, _page_length=None) %}
+    <a href="{{url_for(request.endpoint, page=_page or page, protocoltype=protocoltype_id, search=search_term, state_open=state_open, page_length=_page_length or page_length)}}">{{text}}</a>
 {% endmacro %}
 
 {% block content %}
 <div class="container">
     {{render_form(search_form, class_="form-inline", action_url=url_for("list_todos"), action_text="Suchen", labels_visible=False, method="GET")}}
     {{render_table(todos_table)}}
-    <div class="centered">
-        {% if page > page_diff %}
-            {{page_link(0, "<<")}}
-        {% endif %}
-        {% for p in range(max(0, page - page_diff), min(page_count, page + page_diff + 1)) %}
-            {% if p != page %}
-                {{page_link(p, p + 1)}}
-            {% else %}
-                Seite {{p + 1}}
-            {% endif %}
-        {% endfor %}
-        {% if page < page_count - page_diff - 1 %}
-            {{page_link(page_count - 1, ">>")}}
-        {% endif %}
-    </div>
+    {% include "pagination-footer.html" %}
 </div>
 {% endblock %}
diff --git a/views/forms.py b/views/forms.py
index 94f5dfa583fb02e9c3322fab12a364a56a66564c..e6f228706288d5108e6b1164266533a2675a06cc 100644
--- a/views/forms.py
+++ b/views/forms.py
@@ -209,10 +209,10 @@ class DecisionSearchForm(SearchForm):
         self.decisioncategory_id.choices = get_category_choices(categories)
 
 class ProtocolSearchForm(SearchForm):
-    open = SelectField("Offen", choices=[(-1, "Alle"), (0, "Geplant"), (1, "Fertig")], coerce=int)
+    state_open = SelectField("Offen", choices=[(-1, "Alle"), (0, "Geplant"), (1, "Fertig")], coerce=int)
 
 class TodoSearchForm(SearchForm):
-    open = SelectField("Offen", choices=[(-1, "Alle"), (0, "Offen"), (1, "Erledigt")], coerce=int)
+    state_open = SelectField("Offen", choices=[(-1, "Alle"), (0, "Offen"), (1, "Erledigt")], coerce=int)
 
 class NewTodoForm(FlaskForm):
     protocoltype_id = SelectField("Typ", choices=[], coerce=int)